#include "nodes/parsenodes.h"
#include "utils/array.h"
#include "utils/snapshot.h"
Go to the source code of this file.
#define ACL_ALL_RIGHTS_COLUMN (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_REFERENCES) |
Definition at line 147 of file acl.h.
Referenced by ExecGrant_Attribute(), and ExecGrant_Relation().
#define ACL_ALL_RIGHTS_DATABASE (ACL_CREATE|ACL_CREATE_TEMP|ACL_CONNECT) |
#define ACL_ALL_RIGHTS_RELATION (ACL_INSERT|ACL_SELECT|ACL_UPDATE|ACL_DELETE|ACL_TRUNCATE|ACL_REFERENCES|ACL_TRIGGER) |
Definition at line 148 of file acl.h.
Referenced by ExecGrant_Relation(), and ExecuteGrantStmt().
#define ACL_ALL_RIGHTS_SEQUENCE (ACL_USAGE|ACL_SELECT|ACL_UPDATE) |
Definition at line 149 of file acl.h.
Referenced by ExecGrant_Relation().
#define ACL_ALL_RIGHTS_STR "arwdDxtXUCTc" |
Definition at line 142 of file acl.h.
Referenced by aclitemout(), and aclparse().
#define ACL_CONNECT_CHR 'c' |
Definition at line 139 of file acl.h.
Referenced by aclparse().
#define ACL_CREATE_CHR 'C' |
Definition at line 137 of file acl.h.
Referenced by aclparse().
#define ACL_CREATE_TEMP_CHR 'T' |
Definition at line 138 of file acl.h.
Referenced by aclparse().
#define ACL_DAT | ( | ACL | ) | ((AclItem *) ARR_DATA_PTR(ACL)) |
Definition at line 100 of file acl.h.
Referenced by aclconcat(), aclcontains(), aclcopy(), acldefault(), aclequal(), aclexplode(), aclitemsort(), aclmask(), aclmask_direct(), aclmembers(), aclmerge(), aclnewowner(), aclupdate(), check_circularity(), and recursive_revoke().
#define ACL_DELETE_CHR 'd' |
Definition at line 131 of file acl.h.
Referenced by aclparse().
#define ACL_EXECUTE_CHR 'X' |
Definition at line 135 of file acl.h.
Referenced by aclparse().
#define ACL_GRANT_OPTION_FOR | ( | privs | ) | (((AclMode) (privs) & 0xFFFF) << 16) |
Definition at line 61 of file acl.h.
Referenced by check_circularity(), convert_column_priv_string(), convert_database_priv_string(), convert_foreign_data_wrapper_priv_string(), convert_function_priv_string(), convert_language_priv_string(), convert_role_priv_string(), convert_schema_priv_string(), convert_server_priv_string(), convert_table_priv_string(), convert_tablespace_priv_string(), convert_type_priv_string(), pg_role_aclcheck(), recursive_revoke(), restrict_and_check_grant(), and select_best_grantor().
#define ACL_ID_PUBLIC 0 |
Definition at line 37 of file acl.h.
Referenced by aclitemout(), aclmask(), aclmembers(), aclupdate(), check_circularity(), ExecAlterDefaultPrivilegesStmt(), ExecuteGrantStmt(), and merge_acl_with_grant().
#define ACL_INSERT_CHR 'a' |
Definition at line 128 of file acl.h.
Referenced by aclparse().
#define ACL_MODECHG_ADD 1 |
Definition at line 120 of file acl.h.
Referenced by aclmerge(), aclupdate(), and merge_acl_with_grant().
#define ACL_MODECHG_DEL 2 |
Definition at line 121 of file acl.h.
Referenced by aclupdate(), check_circularity(), and recursive_revoke().
#define ACL_MODECHG_EQL 3 |
Definition at line 122 of file acl.h.
Referenced by aclupdate().
#define ACL_N_SIZE | ( | N | ) | (ARR_OVERHEAD_NONULLS(1) + ((N) * sizeof(AclItem))) |
Definition at line 101 of file acl.h.
Referenced by aclnewowner(), aclupdate(), and allocacl().
#define ACL_NUM | ( | ACL | ) | (ARR_DIMS(ACL)[0]) |
Definition at line 99 of file acl.h.
Referenced by aclconcat(), aclcontains(), aclcopy(), aclequal(), aclexplode(), aclitemsort(), aclmask(), aclmask_direct(), aclmembers(), aclmerge(), aclnewowner(), aclupdate(), check_circularity(), ExecGrant_Attribute(), and recursive_revoke().
#define ACL_OPTION_TO_PRIVS | ( | privs | ) | (((AclMode) (privs) >> 16) & 0xFFFF) |
Definition at line 62 of file acl.h.
Referenced by check_circularity(), recursive_revoke(), and restrict_and_check_grant().
#define ACL_REFERENCES_CHR 'x' |
Definition at line 133 of file acl.h.
Referenced by aclparse().
#define ACL_SELECT_CHR 'r' |
Definition at line 129 of file acl.h.
Referenced by aclparse().
#define ACL_SIZE | ( | ACL | ) | ARR_SIZE(ACL) |
Definition at line 102 of file acl.h.
Referenced by aclupdate(), and check_circularity().
#define ACL_TRIGGER_CHR 't' |
Definition at line 134 of file acl.h.
Referenced by aclparse().
#define ACL_TRUNCATE_CHR 'D' |
Definition at line 132 of file acl.h.
Referenced by aclparse().
#define ACL_UPDATE_CHR 'w' |
Definition at line 130 of file acl.h.
Referenced by aclparse().
#define ACL_USAGE_CHR 'U' |
Definition at line 136 of file acl.h.
Referenced by aclparse().
#define ACLITEM_ALL_GOPTION_BITS ((AclMode) 0xFFFF << 16) |
Definition at line 79 of file acl.h.
Referenced by aclmask(), and aclmask_direct().
#define ACLITEM_GET_GOPTIONS | ( | item | ) | (((item).ai_privs >> 16) & 0xFFFF) |
Definition at line 58 of file acl.h.
Referenced by aclexplode(), aclitemout(), aclupdate(), and check_circularity().
#define ACLITEM_GET_PRIVS | ( | item | ) | ((item).ai_privs & 0xFFFF) |
Definition at line 57 of file acl.h.
Referenced by aclexplode(), aclitemout(), and recursive_revoke().
#define ACLITEM_GET_RIGHTS | ( | item | ) | ((item).ai_privs) |
Definition at line 59 of file acl.h.
Referenced by aclcontains(), aclnewowner(), and aclupdate().
#define ACLITEM_SET_GOPTIONS | ( | item, | ||
goptions | ||||
) |
#define ACLITEM_SET_PRIVS | ( | item, | ||
privs | ||||
) |
#define ACLITEM_SET_PRIVS_GOPTIONS | ( | item, | ||
privs, | ||||
goptions | ||||
) |
((item).ai_privs = ((AclMode) (privs) & 0xFFFF) | \ (((AclMode) (goptions) & 0xFFFF) << 16))
Definition at line 73 of file acl.h.
Referenced by acldefault(), aclparse(), aclupdate(), makeaclitem(), merge_acl_with_grant(), and recursive_revoke().
#define ACLITEM_SET_RIGHTS | ( | item, | ||
rights | ||||
) | ((item).ai_privs = (AclMode) (rights)) |
Definition at line 70 of file acl.h.
Referenced by aclnewowner(), and aclupdate().
#define DatumGetAclItemP | ( | X | ) | ((AclItem *) DatumGetPointer(X)) |
#define DatumGetAclP | ( | X | ) | ((Acl *) PG_DETOAST_DATUM(X)) |
Definition at line 111 of file acl.h.
Referenced by AlterDatabaseOwner(), AlterObjectOwner_internal(), AlterSchemaOwner_internal(), ATExecChangeOwner(), change_owner_fix_column_acls(), pg_attribute_aclmask(), pg_class_aclmask(), pg_database_aclmask(), pg_foreign_data_wrapper_aclmask(), pg_foreign_server_aclmask(), pg_language_aclmask(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_proc_aclmask(), pg_tablespace_aclmask(), and pg_type_aclmask().
#define DatumGetAclPCopy | ( | X | ) | ((Acl *) PG_DETOAST_DATUM_COPY(X)) |
Definition at line 112 of file acl.h.
Referenced by ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), get_default_acl_internal(), and SetDefaultACL().
#define PG_GETARG_ACL_P | ( | n | ) | DatumGetAclP(PG_GETARG_DATUM(n)) |
Definition at line 113 of file acl.h.
Referenced by aclcontains(), and aclexplode().
#define PG_GETARG_ACL_P_COPY | ( | n | ) | DatumGetAclPCopy(PG_GETARG_DATUM(n)) |
#define PG_GETARG_ACLITEM_P | ( | n | ) | DatumGetAclItemP(PG_GETARG_DATUM(n)) |
Definition at line 108 of file acl.h.
Referenced by aclcontains(), aclitem_eq(), aclitemout(), and hash_aclitem().
#define PG_RETURN_ACL_P | ( | x | ) | PG_RETURN_POINTER(x) |
Definition at line 115 of file acl.h.
Referenced by acldefault_sql().
#define PG_RETURN_ACLITEM_P | ( | x | ) | PG_RETURN_POINTER(x) |
Definition at line 109 of file acl.h.
Referenced by aclitemin(), and makeaclitem().
typedef enum AclObjectKind AclObjectKind |
enum AclMaskHow |
Definition at line 161 of file acl.h.
{ ACLMASK_ALL, /* normal case: compute all bits */ ACLMASK_ANY /* return when result is known nonzero */ } AclMaskHow;
enum AclObjectKind |
Definition at line 177 of file acl.h.
{ ACL_KIND_COLUMN, /* pg_attribute */ ACL_KIND_CLASS, /* pg_class */ ACL_KIND_SEQUENCE, /* pg_sequence */ ACL_KIND_DATABASE, /* pg_database */ ACL_KIND_PROC, /* pg_proc */ ACL_KIND_OPER, /* pg_operator */ ACL_KIND_TYPE, /* pg_type */ ACL_KIND_LANGUAGE, /* pg_language */ ACL_KIND_LARGEOBJECT, /* pg_largeobject */ ACL_KIND_NAMESPACE, /* pg_namespace */ ACL_KIND_OPCLASS, /* pg_opclass */ ACL_KIND_OPFAMILY, /* pg_opfamily */ ACL_KIND_COLLATION, /* pg_collation */ ACL_KIND_CONVERSION, /* pg_conversion */ ACL_KIND_TABLESPACE, /* pg_tablespace */ ACL_KIND_TSDICTIONARY, /* pg_ts_dict */ ACL_KIND_TSCONFIGURATION, /* pg_ts_config */ ACL_KIND_FDW, /* pg_foreign_data_wrapper */ ACL_KIND_FOREIGN_SERVER, /* pg_foreign_server */ ACL_KIND_EVENT_TRIGGER, /* pg_event_trigger */ ACL_KIND_EXTENSION, /* pg_extension */ MAX_ACL_KIND /* MUST BE LAST */ } AclObjectKind;
enum AclResult |
Definition at line 168 of file acl.h.
{ ACLCHECK_OK = 0, ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER } AclResult;
void aclcheck_error | ( | AclResult | aclerr, | |
AclObjectKind | objectkind, | |||
const char * | objectname | |||
) |
Definition at line 3362 of file aclchk.c.
References ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog, ereport, errcode(), errmsg(), and ERROR.
Referenced by aclcheck_error_type(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOpFamilyAdd(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterSequence(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepSetStatistics(), ATPrepSetTableSpace(), ATSimplePermissions(), calculate_database_size(), calculate_tablespace_size(), check_object_ownership(), check_temp_tablespaces(), checkFkeyPermissions(), CheckRelationOwnership(), compute_return_type(), create_proc_lang(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreateSchemaCommand(), CreateTrigger(), currtid_byrelname(), currtid_byreloid(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), dropdb(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecCheckRTPerms(), ExecEvalArrayCoerceExpr(), ExecInitAgg(), ExecInitWindowAgg(), ExecuteDoStmt(), ExecuteTruncate(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), get_rel_from_relname(), HandleFunctionRequest(), init_fcache(), initialize_peragg(), LockTableRecurse(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), MergeAttributes(), movedb(), OperatorCreate(), pgrowlocks(), ProcedureCreate(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), ReindexDatabase(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), restrict_and_check_grant(), SetDefaultACLsInSchemas(), transformTableLikeClause(), truncate_check_rel(), TypeCreate(), and user_mapping_ddl_aclcheck().
{ switch (aclerr) { case ACLCHECK_OK: /* no error, so return to caller */ break; case ACLCHECK_NO_PRIV: ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg(no_priv_msg[objectkind], objectname))); break; case ACLCHECK_NOT_OWNER: ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg(not_owner_msg[objectkind], objectname))); break; default: elog(ERROR, "unrecognized AclResult: %d", (int) aclerr); break; } }
void aclcheck_error_col | ( | AclResult | aclerr, | |
AclObjectKind | objectkind, | |||
const char * | objectname, | |||
const char * | colname | |||
) |
Definition at line 3388 of file aclchk.c.
References ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog, ereport, errcode(), errmsg(), and ERROR.
Referenced by restrict_and_check_grant().
{ switch (aclerr) { case ACLCHECK_OK: /* no error, so return to caller */ break; case ACLCHECK_NO_PRIV: ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied for column \"%s\" of relation \"%s\"", colname, objectname))); break; case ACLCHECK_NOT_OWNER: /* relation msg is OK since columns don't have separate owners */ ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg(not_owner_msg[objectkind], objectname))); break; default: elog(ERROR, "unrecognized AclResult: %d", (int) aclerr); break; } }
Definition at line 3420 of file aclchk.c.
References ACL_KIND_TYPE, aclcheck_error(), format_type_be(), and get_element_type().
Referenced by AggregateCreate(), AlterTypeNamespace_oid(), AlterTypeOwner(), ATExecAddColumn(), ATPrepAlterColumnType(), BuildDescForRelation(), check_object_ownership(), checkDomainOwner(), checkEnumOwner(), compute_return_type(), CreateCast(), DefineDomain(), DefineOpClass(), DefineOperator(), DefineRelation(), examine_parameter_list(), and RenameType().
{ Oid element_type = get_element_type(typeOid); aclcheck_error(aclerr, ACL_KIND_TYPE, format_type_be(element_type ? element_type : typeOid)); }
Definition at line 426 of file acl.c.
References ACL_DAT, ACL_NUM, and allocacl().
Referenced by ExecGrant_Attribute().
Datum aclcontains | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1553 of file acl.c.
References ACL_DAT, ACL_NUM, ACLITEM_GET_RIGHTS, AclItem::ai_grantee, AclItem::ai_grantor, check_acl(), i, PG_GETARG_ACL_P, PG_GETARG_ACLITEM_P, and PG_RETURN_BOOL.
{ Acl *acl = PG_GETARG_ACL_P(0); AclItem *aip = PG_GETARG_ACLITEM_P(1); AclItem *aidat; int i, num; check_acl(acl); num = ACL_NUM(acl); aidat = ACL_DAT(acl); for (i = 0; i < num; ++i) { if (aip->ai_grantee == aidat[i].ai_grantee && aip->ai_grantor == aidat[i].ai_grantor && (ACLITEM_GET_RIGHTS(*aip) & ACLITEM_GET_RIGHTS(aidat[i])) == ACLITEM_GET_RIGHTS(*aip)) PG_RETURN_BOOL(true); } PG_RETURN_BOOL(false); }
Definition at line 406 of file acl.c.
References ACL_DAT, ACL_NUM, and allocacl().
Referenced by aclmerge(), ExecGrant_Relation(), and SetDefaultACL().
Acl* acldefault | ( | GrantObjectType | objtype, | |
Oid | ownerId | |||
) |
Definition at line 731 of file acl.c.
References ACL_CREATE_TEMP, ACL_DAT, ACL_NO_RIGHTS, ACL_OBJECT_COLUMN, ACL_OBJECT_DATABASE, ACL_OBJECT_DOMAIN, ACL_OBJECT_FDW, ACL_OBJECT_FOREIGN_SERVER, ACL_OBJECT_FUNCTION, ACL_OBJECT_LANGUAGE, ACL_OBJECT_LARGEOBJECT, ACL_OBJECT_NAMESPACE, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TABLESPACE, ACL_OBJECT_TYPE, ACLITEM_SET_PRIVS_GOPTIONS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), elog, and ERROR.
Referenced by acldefault_sql(), ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), get_user_default_acl(), pg_class_aclmask(), pg_database_aclmask(), pg_foreign_data_wrapper_aclmask(), pg_foreign_server_aclmask(), pg_language_aclmask(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_proc_aclmask(), pg_tablespace_aclmask(), pg_type_aclmask(), and SetDefaultACL().
{ AclMode world_default; AclMode owner_default; int nacl; Acl *acl; AclItem *aip; switch (objtype) { case ACL_OBJECT_COLUMN: /* by default, columns have no extra privileges */ world_default = ACL_NO_RIGHTS; owner_default = ACL_NO_RIGHTS; break; case ACL_OBJECT_RELATION: world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_RELATION; break; case ACL_OBJECT_SEQUENCE: world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_SEQUENCE; break; case ACL_OBJECT_DATABASE: /* for backwards compatibility, grant some rights by default */ world_default = ACL_CREATE_TEMP | ACL_CONNECT; owner_default = ACL_ALL_RIGHTS_DATABASE; break; case ACL_OBJECT_FUNCTION: /* Grant EXECUTE by default, for now */ world_default = ACL_EXECUTE; owner_default = ACL_ALL_RIGHTS_FUNCTION; break; case ACL_OBJECT_LANGUAGE: /* Grant USAGE by default, for now */ world_default = ACL_USAGE; owner_default = ACL_ALL_RIGHTS_LANGUAGE; break; case ACL_OBJECT_LARGEOBJECT: world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_LARGEOBJECT; break; case ACL_OBJECT_NAMESPACE: world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_NAMESPACE; break; case ACL_OBJECT_TABLESPACE: world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_TABLESPACE; break; case ACL_OBJECT_FDW: world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_FDW; break; case ACL_OBJECT_FOREIGN_SERVER: world_default = ACL_NO_RIGHTS; owner_default = ACL_ALL_RIGHTS_FOREIGN_SERVER; break; case ACL_OBJECT_DOMAIN: case ACL_OBJECT_TYPE: world_default = ACL_USAGE; owner_default = ACL_ALL_RIGHTS_TYPE; break; default: elog(ERROR, "unrecognized objtype: %d", (int) objtype); world_default = ACL_NO_RIGHTS; /* keep compiler quiet */ owner_default = ACL_NO_RIGHTS; break; } nacl = 0; if (world_default != ACL_NO_RIGHTS) nacl++; if (owner_default != ACL_NO_RIGHTS) nacl++; acl = allocacl(nacl); aip = ACL_DAT(acl); if (world_default != ACL_NO_RIGHTS) { aip->ai_grantee = ACL_ID_PUBLIC; aip->ai_grantor = ownerId; ACLITEM_SET_PRIVS_GOPTIONS(*aip, world_default, ACL_NO_RIGHTS); aip++; } /* * Note that the owner's entry shows all ordinary privileges but no grant * options. This is because his grant options come "from the system" and * not from his own efforts. (The SQL spec says that the owner's rights * come from a "_SYSTEM" authid.) However, we do consider that the * owner's ordinary privileges are self-granted; this lets him revoke * them. We implement the owner's grant options without any explicit * "_SYSTEM"-like ACL entry, by internally special-casing the owner * wherever we are testing grant options. */ if (owner_default != ACL_NO_RIGHTS) { aip->ai_grantee = ownerId; aip->ai_grantor = ownerId; ACLITEM_SET_PRIVS_GOPTIONS(*aip, owner_default, ACL_NO_RIGHTS); } return acl; }
Datum acldefault_sql | ( | PG_FUNCTION_ARGS | ) |
Definition at line 845 of file acl.c.
References acldefault(), elog, ERROR, PG_GETARG_CHAR, PG_GETARG_OID, and PG_RETURN_ACL_P.
{ char objtypec = PG_GETARG_CHAR(0); Oid owner = PG_GETARG_OID(1); GrantObjectType objtype = 0; switch (objtypec) { case 'c': objtype = ACL_OBJECT_COLUMN; break; case 'r': objtype = ACL_OBJECT_RELATION; break; case 's': objtype = ACL_OBJECT_SEQUENCE; break; case 'd': objtype = ACL_OBJECT_DATABASE; break; case 'f': objtype = ACL_OBJECT_FUNCTION; break; case 'l': objtype = ACL_OBJECT_LANGUAGE; break; case 'L': objtype = ACL_OBJECT_LARGEOBJECT; break; case 'n': objtype = ACL_OBJECT_NAMESPACE; break; case 't': objtype = ACL_OBJECT_TABLESPACE; break; case 'F': objtype = ACL_OBJECT_FDW; break; case 'S': objtype = ACL_OBJECT_FOREIGN_SERVER; break; case 'T': objtype = ACL_OBJECT_TYPE; break; default: elog(ERROR, "unrecognized objtype abbreviation: %c", objtypec); } PG_RETURN_ACL_P(acldefault(objtype, owner)); }
Definition at line 508 of file acl.c.
References ACL_DAT, ACL_NUM, memcmp(), and NULL.
Referenced by get_user_default_acl(), and SetDefaultACL().
{ /* Check for cases where one or both are empty/null */ if (left_acl == NULL || ACL_NUM(left_acl) == 0) { if (right_acl == NULL || ACL_NUM(right_acl) == 0) return true; else return false; } else { if (right_acl == NULL || ACL_NUM(right_acl) == 0) return false; } if (ACL_NUM(left_acl) != ACL_NUM(right_acl)) return false; if (memcmp(ACL_DAT(left_acl), ACL_DAT(right_acl), ACL_NUM(left_acl) * sizeof(AclItem)) == 0) return true; return false; }
Datum aclexplode | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1746 of file acl.c.
References ACL_DAT, ACL_NUM, ACLITEM_GET_GOPTIONS, ACLITEM_GET_PRIVS, AclItem::ai_grantee, AclItem::ai_grantor, BlessTupleDesc(), BoolGetDatum, BOOLOID, check_acl(), convert_aclright_to_string(), CreateTemplateTupleDesc(), CStringGetTextDatum, heap_form_tuple(), HeapTupleGetDatum, MemoryContextSwitchTo(), MemSet, FuncCallContext::multi_call_memory_ctx, N_ACL_RIGHTS, ObjectIdGetDatum, OIDOID, palloc(), PG_GETARG_ACL_P, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, TEXTOID, FuncCallContext::tuple_desc, TupleDescInitEntry(), FuncCallContext::user_fctx, and values.
{ Acl *acl = PG_GETARG_ACL_P(0); FuncCallContext *funcctx; int *idx; AclItem *aidat; if (SRF_IS_FIRSTCALL()) { TupleDesc tupdesc; MemoryContext oldcontext; check_acl(acl); funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /* * build tupdesc for result tuples (matches out parameters in pg_proc * entry) */ tupdesc = CreateTemplateTupleDesc(4, false); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "grantor", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "grantee", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 3, "privilege_type", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 4, "is_grantable", BOOLOID, -1, 0); funcctx->tuple_desc = BlessTupleDesc(tupdesc); /* allocate memory for user context */ idx = (int *) palloc(sizeof(int[2])); idx[0] = 0; /* ACL array item index */ idx[1] = -1; /* privilege type counter */ funcctx->user_fctx = (void *) idx; MemoryContextSwitchTo(oldcontext); } funcctx = SRF_PERCALL_SETUP(); idx = (int *) funcctx->user_fctx; aidat = ACL_DAT(acl); /* need test here in case acl has no items */ while (idx[0] < ACL_NUM(acl)) { AclItem *aidata; AclMode priv_bit; idx[1]++; if (idx[1] == N_ACL_RIGHTS) { idx[1] = 0; idx[0]++; if (idx[0] >= ACL_NUM(acl)) /* done */ break; } aidata = &aidat[idx[0]]; priv_bit = 1 << idx[1]; if (ACLITEM_GET_PRIVS(*aidata) & priv_bit) { Datum result; Datum values[4]; bool nulls[4]; HeapTuple tuple; values[0] = ObjectIdGetDatum(aidata->ai_grantor); values[1] = ObjectIdGetDatum(aidata->ai_grantee); values[2] = CStringGetTextDatum(convert_aclright_to_string(priv_bit)); values[3] = BoolGetDatum((ACLITEM_GET_GOPTIONS(*aidata) & priv_bit) != 0); MemSet(nulls, 0, sizeof(nulls)); tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); SRF_RETURN_NEXT(funcctx, result); } } SRF_RETURN_DONE(funcctx); }
Datum aclinsert | ( | PG_FUNCTION_ARGS | ) |
Datum aclitem_eq | ( | PG_FUNCTION_ARGS | ) |
Definition at line 692 of file acl.c.
References a1, a2, AclItem::ai_grantee, AclItem::ai_grantor, AclItem::ai_privs, PG_GETARG_ACLITEM_P, and PG_RETURN_BOOL.
{ AclItem *a1 = PG_GETARG_ACLITEM_P(0); AclItem *a2 = PG_GETARG_ACLITEM_P(1); bool result; result = a1->ai_privs == a2->ai_privs && a1->ai_grantee == a2->ai_grantee && a1->ai_grantor == a2->ai_grantor; PG_RETURN_BOOL(result); }
Datum aclitemin | ( | PG_FUNCTION_ARGS | ) |
Definition at line 564 of file acl.c.
References aclparse(), ereport, errcode(), errmsg(), ERROR, palloc(), PG_GETARG_CSTRING, and PG_RETURN_ACLITEM_P.
{ const char *s = PG_GETARG_CSTRING(0); AclItem *aip; aip = (AclItem *) palloc(sizeof(AclItem)); s = aclparse(s, aip); while (isspace((unsigned char) *s)) ++s; if (*s) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("extra garbage at the end of the ACL specification"))); PG_RETURN_ACLITEM_P(aip); }
Datum aclitemout | ( | PG_FUNCTION_ARGS | ) |
Definition at line 590 of file acl.c.
References ACL_ALL_RIGHTS_STR, ACL_ID_PUBLIC, ACLITEM_GET_GOPTIONS, ACLITEM_GET_PRIVS, AclItem::ai_grantee, AclItem::ai_grantor, AUTHOID, GETSTRUCT, HeapTupleIsValid, i, N_ACL_RIGHTS, NAMEDATALEN, NameStr, ObjectIdGetDatum, palloc(), PG_GETARG_ACLITEM_P, PG_RETURN_CSTRING, putid(), ReleaseSysCache(), and SearchSysCache1.
{ AclItem *aip = PG_GETARG_ACLITEM_P(0); char *p; char *out; HeapTuple htup; unsigned i; out = palloc(strlen("=/") + 2 * N_ACL_RIGHTS + 2 * (2 * NAMEDATALEN + 2) + 1); p = out; *p = '\0'; if (aip->ai_grantee != ACL_ID_PUBLIC) { htup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(aip->ai_grantee)); if (HeapTupleIsValid(htup)) { putid(p, NameStr(((Form_pg_authid) GETSTRUCT(htup))->rolname)); ReleaseSysCache(htup); } else { /* Generate numeric OID if we don't find an entry */ sprintf(p, "%u", aip->ai_grantee); } } while (*p) ++p; *p++ = '='; for (i = 0; i < N_ACL_RIGHTS; ++i) { if (ACLITEM_GET_PRIVS(*aip) & (1 << i)) *p++ = ACL_ALL_RIGHTS_STR[i]; if (ACLITEM_GET_GOPTIONS(*aip) & (1 << i)) *p++ = '*'; } *p++ = '/'; *p = '\0'; htup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(aip->ai_grantor)); if (HeapTupleIsValid(htup)) { putid(p, NameStr(((Form_pg_authid) GETSTRUCT(htup))->rolname)); ReleaseSysCache(htup); } else { /* Generate numeric OID if we don't find an entry */ sprintf(p, "%u", aip->ai_grantor); } PG_RETURN_CSTRING(out); }
void aclitemsort | ( | Acl * | acl | ) |
Definition at line 494 of file acl.c.
References ACL_DAT, ACL_NUM, aclitemComparator(), NULL, and qsort.
Referenced by get_user_default_acl(), and SetDefaultACL().
Definition at line 1304 of file acl.c.
References ACL_DAT, ACL_ID_PUBLIC, ACL_NUM, ACLITEM_ALL_GOPTION_BITS, ACLMASK_ALL, AclItem::ai_grantee, AclItem::ai_privs, check_acl(), elog, ERROR, has_privs_of_role(), i, NULL, and remaining.
Referenced by check_circularity(), pg_attribute_aclmask(), pg_class_aclmask(), pg_database_aclmask(), pg_foreign_data_wrapper_aclmask(), pg_foreign_server_aclmask(), pg_language_aclmask(), pg_largeobject_aclmask_snapshot(), pg_namespace_aclmask(), pg_proc_aclmask(), pg_tablespace_aclmask(), pg_type_aclmask(), and recursive_revoke().
{ AclMode result; AclMode remaining; AclItem *aidat; int i, num; /* * Null ACL should not happen, since caller should have inserted * appropriate default */ if (acl == NULL) elog(ERROR, "null ACL"); check_acl(acl); /* Quick exit for mask == 0 */ if (mask == 0) return 0; result = 0; /* Owner always implicitly has all grant options */ if ((mask & ACLITEM_ALL_GOPTION_BITS) && has_privs_of_role(roleid, ownerId)) { result = mask & ACLITEM_ALL_GOPTION_BITS; if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0)) return result; } num = ACL_NUM(acl); aidat = ACL_DAT(acl); /* * Check privileges granted directly to roleid or to public */ for (i = 0; i < num; i++) { AclItem *aidata = &aidat[i]; if (aidata->ai_grantee == ACL_ID_PUBLIC || aidata->ai_grantee == roleid) { result |= aidata->ai_privs & mask; if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0)) return result; } } /* * Check privileges granted indirectly via role memberships. We do this in * a separate pass to minimize expensive indirect membership tests. In * particular, it's worth testing whether a given ACL entry grants any * privileges still of interest before we perform the has_privs_of_role * test. */ remaining = mask & ~result; for (i = 0; i < num; i++) { AclItem *aidata = &aidat[i]; if (aidata->ai_grantee == ACL_ID_PUBLIC || aidata->ai_grantee == roleid) continue; /* already checked it */ if ((aidata->ai_privs & remaining) && has_privs_of_role(roleid, aidata->ai_grantee)) { result |= aidata->ai_privs & mask; if ((how == ACLMASK_ALL) ? (result == mask) : (result != 0)) return result; remaining = mask & ~result; } } return result; }
Definition at line 1456 of file acl.c.
References ACL_DAT, ACL_ID_PUBLIC, ACL_NUM, AclItem::ai_grantee, AclItem::ai_grantor, check_acl(), i, sort-test::list, NULL, oidComparator(), palloc(), and qsort.
Referenced by ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), heap_create_with_catalog(), ProcedureCreate(), and SetDefaultACL().
{ Oid *list; const AclItem *acldat; int i, j, k; if (acl == NULL || ACL_NUM(acl) == 0) { *roleids = NULL; return 0; } check_acl(acl); /* Allocate the worst-case space requirement */ list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid)); acldat = ACL_DAT(acl); /* * Walk the ACL collecting mentioned RoleIds. */ j = 0; for (i = 0; i < ACL_NUM(acl); i++) { const AclItem *ai = &acldat[i]; if (ai->ai_grantee != ACL_ID_PUBLIC) list[j++] = ai->ai_grantee; /* grantor is currently never PUBLIC, but let's check anyway */ if (ai->ai_grantor != ACL_ID_PUBLIC) list[j++] = ai->ai_grantor; } /* Sort the array */ qsort(list, j, sizeof(Oid), oidComparator); /* Remove duplicates from the array */ k = 0; for (i = 1; i < j; i++) { if (list[k] != list[i]) list[++k] = list[i]; } /* * We could repalloc the array down to minimum size, but it's hardly worth * it since it's only transient memory. */ *roleids = list; return k + 1; }
Definition at line 450 of file acl.c.
References ACL_DAT, ACL_MODECHG_ADD, ACL_NUM, aclcopy(), aclupdate(), DROP_RESTRICT, i, NULL, and pfree().
Referenced by get_user_default_acl().
{ Acl *result_acl; AclItem *aip; int i, num; /* Check for cases where one or both are empty/null */ if (left_acl == NULL || ACL_NUM(left_acl) == 0) { if (right_acl == NULL || ACL_NUM(right_acl) == 0) return NULL; else return aclcopy(right_acl); } else { if (right_acl == NULL || ACL_NUM(right_acl) == 0) return aclcopy(left_acl); } /* Merge them the hard way, one item at a time */ result_acl = aclcopy(left_acl); aip = ACL_DAT(right_acl); num = ACL_NUM(right_acl); for (i = 0; i < num; i++, aip++) { Acl *tmp_acl; tmp_acl = aclupdate(result_acl, aip, ACL_MODECHG_ADD, ownerId, DROP_RESTRICT); pfree(result_acl); result_acl = tmp_acl; } return result_acl; }
Definition at line 1035 of file acl.c.
References ACL_DAT, ACL_N_SIZE, ACL_NO_RIGHTS, ACL_NUM, ACLITEM_GET_RIGHTS, aclitem_match(), ACLITEM_SET_RIGHTS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), ARR_DIMS, check_acl(), and SET_VARSIZE.
Referenced by AlterDatabaseOwner(), AlterObjectOwner_internal(), AlterSchemaOwner_internal(), ATExecChangeOwner(), and change_owner_fix_column_acls().
{ Acl *new_acl; AclItem *new_aip; AclItem *old_aip; AclItem *dst_aip; AclItem *src_aip; AclItem *targ_aip; bool newpresent = false; int dst, src, targ, num; check_acl(old_acl); /* * Make a copy of the given ACL, substituting new owner ID for old * wherever it appears as either grantor or grantee. Also note if the new * owner ID is already present. */ num = ACL_NUM(old_acl); old_aip = ACL_DAT(old_acl); new_acl = allocacl(num); new_aip = ACL_DAT(new_acl); memcpy(new_aip, old_aip, num * sizeof(AclItem)); for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++) { if (dst_aip->ai_grantor == oldOwnerId) dst_aip->ai_grantor = newOwnerId; else if (dst_aip->ai_grantor == newOwnerId) newpresent = true; if (dst_aip->ai_grantee == oldOwnerId) dst_aip->ai_grantee = newOwnerId; else if (dst_aip->ai_grantee == newOwnerId) newpresent = true; } /* * If the old ACL contained any references to the new owner, then we may * now have generated an ACL containing duplicate entries. Find them and * merge them so that there are not duplicates. (This is relatively * expensive since we use a stupid O(N^2) algorithm, but it's unlikely to * be the normal case.) * * To simplify deletion of duplicate entries, we temporarily leave them in * the array but set their privilege masks to zero; when we reach such an * entry it's just skipped. (Thus, a side effect of this code will be to * remove privilege-free entries, should there be any in the input.) dst * is the next output slot, targ is the currently considered input slot * (always >= dst), and src scans entries to the right of targ looking for * duplicates. Once an entry has been emitted to dst it is known * duplicate-free and need not be considered anymore. */ if (newpresent) { dst = 0; for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++) { /* ignore if deleted in an earlier pass */ if (ACLITEM_GET_RIGHTS(*targ_aip) == ACL_NO_RIGHTS) continue; /* find and merge any duplicates */ for (src = targ + 1, src_aip = targ_aip + 1; src < num; src++, src_aip++) { if (ACLITEM_GET_RIGHTS(*src_aip) == ACL_NO_RIGHTS) continue; if (aclitem_match(targ_aip, src_aip)) { ACLITEM_SET_RIGHTS(*targ_aip, ACLITEM_GET_RIGHTS(*targ_aip) | ACLITEM_GET_RIGHTS(*src_aip)); /* mark the duplicate deleted */ ACLITEM_SET_RIGHTS(*src_aip, ACL_NO_RIGHTS); } } /* and emit to output */ new_aip[dst] = *targ_aip; dst++; } /* Adjust array size to be 'dst' items */ ARR_DIMS(new_acl)[0] = dst; SET_VARSIZE(new_acl, ACL_N_SIZE(dst)); } return new_acl; }
Datum aclremove | ( | PG_FUNCTION_ARGS | ) |
Acl* aclupdate | ( | const Acl * | old_acl, | |
const AclItem * | mod_aip, | |||
int | modechg, | |||
Oid | ownerId, | |||
DropBehavior | behavior | |||
) |
Definition at line 914 of file acl.c.
References ACL_DAT, ACL_ID_PUBLIC, ACL_MODECHG_ADD, ACL_MODECHG_DEL, ACL_MODECHG_EQL, ACL_N_SIZE, ACL_NO_RIGHTS, ACL_NUM, ACL_SIZE, ACLITEM_GET_GOPTIONS, ACLITEM_GET_RIGHTS, aclitem_match(), ACLITEM_SET_PRIVS_GOPTIONS, ACLITEM_SET_RIGHTS, AclItem::ai_grantee, AclItem::ai_grantor, allocacl(), ARR_DIMS, Assert, check_acl(), check_circularity(), memmove, recursive_revoke(), and SET_VARSIZE.
Referenced by aclmerge(), check_circularity(), merge_acl_with_grant(), and recursive_revoke().
{ Acl *new_acl = NULL; AclItem *old_aip, *new_aip = NULL; AclMode old_rights, old_goptions, new_rights, new_goptions; int dst, num; /* Caller probably already checked old_acl, but be safe */ check_acl(old_acl); /* If granting grant options, check for circularity */ if (modechg != ACL_MODECHG_DEL && ACLITEM_GET_GOPTIONS(*mod_aip) != ACL_NO_RIGHTS) check_circularity(old_acl, mod_aip, ownerId); num = ACL_NUM(old_acl); old_aip = ACL_DAT(old_acl); /* * Search the ACL for an existing entry for this grantee and grantor. If * one exists, just modify the entry in-place (well, in the same position, * since we actually return a copy); otherwise, insert the new entry at * the end. */ for (dst = 0; dst < num; ++dst) { if (aclitem_match(mod_aip, old_aip + dst)) { /* found a match, so modify existing item */ new_acl = allocacl(num); new_aip = ACL_DAT(new_acl); memcpy(new_acl, old_acl, ACL_SIZE(old_acl)); break; } } if (dst == num) { /* need to append a new item */ new_acl = allocacl(num + 1); new_aip = ACL_DAT(new_acl); memcpy(new_aip, old_aip, num * sizeof(AclItem)); /* initialize the new entry with no permissions */ new_aip[dst].ai_grantee = mod_aip->ai_grantee; new_aip[dst].ai_grantor = mod_aip->ai_grantor; ACLITEM_SET_PRIVS_GOPTIONS(new_aip[dst], ACL_NO_RIGHTS, ACL_NO_RIGHTS); num++; /* set num to the size of new_acl */ } old_rights = ACLITEM_GET_RIGHTS(new_aip[dst]); old_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]); /* apply the specified permissions change */ switch (modechg) { case ACL_MODECHG_ADD: ACLITEM_SET_RIGHTS(new_aip[dst], old_rights | ACLITEM_GET_RIGHTS(*mod_aip)); break; case ACL_MODECHG_DEL: ACLITEM_SET_RIGHTS(new_aip[dst], old_rights & ~ACLITEM_GET_RIGHTS(*mod_aip)); break; case ACL_MODECHG_EQL: ACLITEM_SET_RIGHTS(new_aip[dst], ACLITEM_GET_RIGHTS(*mod_aip)); break; } new_rights = ACLITEM_GET_RIGHTS(new_aip[dst]); new_goptions = ACLITEM_GET_GOPTIONS(new_aip[dst]); /* * If the adjusted entry has no permissions, delete it from the list. */ if (new_rights == ACL_NO_RIGHTS) { memmove(new_aip + dst, new_aip + dst + 1, (num - dst - 1) * sizeof(AclItem)); /* Adjust array size to be 'num - 1' items */ ARR_DIMS(new_acl)[0] = num - 1; SET_VARSIZE(new_acl, ACL_N_SIZE(num - 1)); } /* * Remove abandoned privileges (cascading revoke). Currently we can only * handle this when the grantee is not PUBLIC. */ if ((old_goptions & ~new_goptions) != 0) { Assert(mod_aip->ai_grantee != ACL_ID_PUBLIC); new_acl = recursive_revoke(new_acl, mod_aip->ai_grantee, (old_goptions & ~new_goptions), ownerId, behavior); } return new_acl; }
Definition at line 4871 of file acl.c.
References ereport, errcode(), errmsg(), ERROR, GetUserNameFromId(), and is_member_of_role().
Referenced by AlterDatabaseOwner(), AlterForeignServerOwner_internal(), AlterObjectOwner_internal(), AlterSchemaOwner_internal(), AlterTypeOwner(), ATExecChangeOwner(), createdb(), CreateSchemaCommand(), and ExecAlterDefaultPrivilegesStmt().
{ if (!is_member_of_role(member, role)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be member of role \"%s\"", GetUserNameFromId(role)))); }
void ExecAlterDefaultPrivilegesStmt | ( | AlterDefaultPrivilegesStmt * | stmt | ) |
Definition at line 854 of file aclchk.c.
References ACL_ID_PUBLIC, ACL_OBJECT_FUNCTION, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TYPE, AlterDefaultPrivilegesStmt::action, InternalDefaultACL::all_privs, DefElem::arg, GrantStmt::behavior, InternalDefaultACL::behavior, check_is_member_of_role(), AccessPriv::cols, DefElem::defname, elog, ereport, errcode(), errmsg(), ERROR, get_role_oid(), gettext_noop, GetUserId(), GrantStmt::grant_option, InternalDefaultACL::grant_option, GrantStmt::grantees, InternalDefaultACL::grantees, GrantStmt::is_grant, InternalDefaultACL::is_grant, lappend_oid(), lfirst, NIL, NULL, GrantStmt::objtype, InternalDefaultACL::objtype, AlterDefaultPrivilegesStmt::options, AccessPriv::priv_name, privilege_to_string(), InternalDefaultACL::privileges, GrantStmt::privileges, InternalDefaultACL::roleid, PrivGrantee::rolname, SetDefaultACLsInSchemas(), string_to_privilege(), and strVal.
Referenced by ProcessUtilitySlow().
{ GrantStmt *action = stmt->action; InternalDefaultACL iacls; ListCell *cell; List *rolenames = NIL; List *nspnames = NIL; DefElem *drolenames = NULL; DefElem *dnspnames = NULL; AclMode all_privileges; const char *errormsg; /* Deconstruct the "options" part of the statement */ foreach(cell, stmt->options) { DefElem *defel = (DefElem *) lfirst(cell); if (strcmp(defel->defname, "schemas") == 0) { if (dnspnames) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); dnspnames = defel; } else if (strcmp(defel->defname, "roles") == 0) { if (drolenames) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("conflicting or redundant options"))); drolenames = defel; } else elog(ERROR, "option \"%s\" not recognized", defel->defname); } if (dnspnames) nspnames = (List *) dnspnames->arg; if (drolenames) rolenames = (List *) drolenames->arg; /* Prepare the InternalDefaultACL representation of the statement */ /* roleid to be filled below */ /* nspid to be filled in SetDefaultACLsInSchemas */ iacls.is_grant = action->is_grant; iacls.objtype = action->objtype; /* all_privs to be filled below */ /* privileges to be filled below */ iacls.grantees = NIL; /* filled below */ iacls.grant_option = action->grant_option; iacls.behavior = action->behavior; /* * Convert the PrivGrantee list into an Oid list. Note that at this point * we insert an ACL_ID_PUBLIC into the list if an empty role name is * detected (which is what the grammar uses if PUBLIC is found), so * downstream there shouldn't be any additional work needed to support * this case. */ foreach(cell, action->grantees) { PrivGrantee *grantee = (PrivGrantee *) lfirst(cell); if (grantee->rolname == NULL) iacls.grantees = lappend_oid(iacls.grantees, ACL_ID_PUBLIC); else iacls.grantees = lappend_oid(iacls.grantees, get_role_oid(grantee->rolname, false)); } /* * Convert action->privileges, a list of privilege strings, into an * AclMode bitmask. */ switch (action->objtype) { case ACL_OBJECT_RELATION: all_privileges = ACL_ALL_RIGHTS_RELATION; errormsg = gettext_noop("invalid privilege type %s for relation"); break; case ACL_OBJECT_SEQUENCE: all_privileges = ACL_ALL_RIGHTS_SEQUENCE; errormsg = gettext_noop("invalid privilege type %s for sequence"); break; case ACL_OBJECT_FUNCTION: all_privileges = ACL_ALL_RIGHTS_FUNCTION; errormsg = gettext_noop("invalid privilege type %s for function"); break; case ACL_OBJECT_TYPE: all_privileges = ACL_ALL_RIGHTS_TYPE; errormsg = gettext_noop("invalid privilege type %s for type"); break; default: elog(ERROR, "unrecognized GrantStmt.objtype: %d", (int) action->objtype); /* keep compiler quiet */ all_privileges = ACL_NO_RIGHTS; errormsg = NULL; } if (action->privileges == NIL) { iacls.all_privs = true; /* * will be turned into ACL_ALL_RIGHTS_* by the internal routines * depending on the object type */ iacls.privileges = ACL_NO_RIGHTS; } else { iacls.all_privs = false; iacls.privileges = ACL_NO_RIGHTS; foreach(cell, action->privileges) { AccessPriv *privnode = (AccessPriv *) lfirst(cell); AclMode priv; if (privnode->cols) ereport(ERROR, (errcode(ERRCODE_INVALID_GRANT_OPERATION), errmsg("default privileges cannot be set for columns"))); if (privnode->priv_name == NULL) /* parser mistake? */ elog(ERROR, "AccessPriv node must specify privilege"); priv = string_to_privilege(privnode->priv_name); if (priv & ~((AclMode) all_privileges)) ereport(ERROR, (errcode(ERRCODE_INVALID_GRANT_OPERATION), errmsg(errormsg, privilege_to_string(priv)))); iacls.privileges |= priv; } } if (rolenames == NIL) { /* Set permissions for myself */ iacls.roleid = GetUserId(); SetDefaultACLsInSchemas(&iacls, nspnames); } else { /* Look up the role OIDs and do permissions checks */ ListCell *rolecell; foreach(rolecell, rolenames) { char *rolename = strVal(lfirst(rolecell)); iacls.roleid = get_role_oid(rolename, false); /* * We insist that calling user be a member of each target role. If * he has that, he could become that role anyway via SET ROLE, so * FOR ROLE is just a syntactic convenience and doesn't give any * special privileges. */ check_is_member_of_role(GetUserId(), iacls.roleid); SetDefaultACLsInSchemas(&iacls, nspnames); } } }
void ExecuteGrantStmt | ( | GrantStmt * | stmt | ) |
Definition at line 388 of file aclchk.c.
References ACL_ALL_RIGHTS_RELATION, ACL_ID_PUBLIC, ACL_OBJECT_DATABASE, ACL_OBJECT_DOMAIN, ACL_OBJECT_FDW, ACL_OBJECT_FOREIGN_SERVER, ACL_OBJECT_FUNCTION, ACL_OBJECT_LANGUAGE, ACL_OBJECT_LARGEOBJECT, ACL_OBJECT_NAMESPACE, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TABLESPACE, ACL_OBJECT_TYPE, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, GrantStmt::behavior, InternalGrant::behavior, InternalGrant::col_privs, AccessPriv::cols, elog, ereport, errcode(), errmsg(), ERROR, ExecGrantStmt_oids(), get_role_oid(), gettext_noop, GrantStmt::grant_option, InternalGrant::grant_option, GrantStmt::grantees, InternalGrant::grantees, GrantStmt::is_grant, InternalGrant::is_grant, lappend(), lappend_oid(), lfirst, NIL, NULL, objectNamesToOids(), GrantStmt::objects, InternalGrant::objects, objectsInSchemaToOids(), GrantStmt::objtype, InternalGrant::objtype, AccessPriv::priv_name, privilege_to_string(), InternalGrant::privileges, GrantStmt::privileges, PrivGrantee::rolname, string_to_privilege(), and GrantStmt::targtype.
Referenced by standard_ProcessUtility().
{ InternalGrant istmt; ListCell *cell; const char *errormsg; AclMode all_privileges; /* * Turn the regular GrantStmt into the InternalGrant form. */ istmt.is_grant = stmt->is_grant; istmt.objtype = stmt->objtype; /* Collect the OIDs of the target objects */ switch (stmt->targtype) { case ACL_TARGET_OBJECT: istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects); break; case ACL_TARGET_ALL_IN_SCHEMA: istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects); break; /* ACL_TARGET_DEFAULTS should not be seen here */ default: elog(ERROR, "unrecognized GrantStmt.targtype: %d", (int) stmt->targtype); } /* all_privs to be filled below */ /* privileges to be filled below */ istmt.col_privs = NIL; /* may get filled below */ istmt.grantees = NIL; /* filled below */ istmt.grant_option = stmt->grant_option; istmt.behavior = stmt->behavior; /* * Convert the PrivGrantee list into an Oid list. Note that at this point * we insert an ACL_ID_PUBLIC into the list if an empty role name is * detected (which is what the grammar uses if PUBLIC is found), so * downstream there shouldn't be any additional work needed to support * this case. */ foreach(cell, stmt->grantees) { PrivGrantee *grantee = (PrivGrantee *) lfirst(cell); if (grantee->rolname == NULL) istmt.grantees = lappend_oid(istmt.grantees, ACL_ID_PUBLIC); else istmt.grantees = lappend_oid(istmt.grantees, get_role_oid(grantee->rolname, false)); } /* * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode * bitmask. Note: objtype can't be ACL_OBJECT_COLUMN. */ switch (stmt->objtype) { /* * Because this might be a sequence, we test both relation and * sequence bits, and later do a more limited test when we know * the object type. */ case ACL_OBJECT_RELATION: all_privileges = ACL_ALL_RIGHTS_RELATION | ACL_ALL_RIGHTS_SEQUENCE; errormsg = gettext_noop("invalid privilege type %s for relation"); break; case ACL_OBJECT_SEQUENCE: all_privileges = ACL_ALL_RIGHTS_SEQUENCE; errormsg = gettext_noop("invalid privilege type %s for sequence"); break; case ACL_OBJECT_DATABASE: all_privileges = ACL_ALL_RIGHTS_DATABASE; errormsg = gettext_noop("invalid privilege type %s for database"); break; case ACL_OBJECT_DOMAIN: all_privileges = ACL_ALL_RIGHTS_TYPE; errormsg = gettext_noop("invalid privilege type %s for domain"); break; case ACL_OBJECT_FUNCTION: all_privileges = ACL_ALL_RIGHTS_FUNCTION; errormsg = gettext_noop("invalid privilege type %s for function"); break; case ACL_OBJECT_LANGUAGE: all_privileges = ACL_ALL_RIGHTS_LANGUAGE; errormsg = gettext_noop("invalid privilege type %s for language"); break; case ACL_OBJECT_LARGEOBJECT: all_privileges = ACL_ALL_RIGHTS_LARGEOBJECT; errormsg = gettext_noop("invalid privilege type %s for large object"); break; case ACL_OBJECT_NAMESPACE: all_privileges = ACL_ALL_RIGHTS_NAMESPACE; errormsg = gettext_noop("invalid privilege type %s for schema"); break; case ACL_OBJECT_TABLESPACE: all_privileges = ACL_ALL_RIGHTS_TABLESPACE; errormsg = gettext_noop("invalid privilege type %s for tablespace"); break; case ACL_OBJECT_TYPE: all_privileges = ACL_ALL_RIGHTS_TYPE; errormsg = gettext_noop("invalid privilege type %s for type"); break; case ACL_OBJECT_FDW: all_privileges = ACL_ALL_RIGHTS_FDW; errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper"); break; case ACL_OBJECT_FOREIGN_SERVER: all_privileges = ACL_ALL_RIGHTS_FOREIGN_SERVER; errormsg = gettext_noop("invalid privilege type %s for foreign server"); break; default: elog(ERROR, "unrecognized GrantStmt.objtype: %d", (int) stmt->objtype); /* keep compiler quiet */ all_privileges = ACL_NO_RIGHTS; errormsg = NULL; } if (stmt->privileges == NIL) { istmt.all_privs = true; /* * will be turned into ACL_ALL_RIGHTS_* by the internal routines * depending on the object type */ istmt.privileges = ACL_NO_RIGHTS; } else { istmt.all_privs = false; istmt.privileges = ACL_NO_RIGHTS; foreach(cell, stmt->privileges) { AccessPriv *privnode = (AccessPriv *) lfirst(cell); AclMode priv; /* * If it's a column-level specification, we just set it aside in * col_privs for the moment; but insist it's for a relation. */ if (privnode->cols) { if (stmt->objtype != ACL_OBJECT_RELATION) ereport(ERROR, (errcode(ERRCODE_INVALID_GRANT_OPERATION), errmsg("column privileges are only valid for relations"))); istmt.col_privs = lappend(istmt.col_privs, privnode); continue; } if (privnode->priv_name == NULL) /* parser mistake? */ elog(ERROR, "AccessPriv node must specify privilege or columns"); priv = string_to_privilege(privnode->priv_name); if (priv & ~((AclMode) all_privileges)) ereport(ERROR, (errcode(ERRCODE_INVALID_GRANT_OPERATION), errmsg(errormsg, privilege_to_string(priv)))); istmt.privileges |= priv; } } ExecGrantStmt_oids(&istmt); }
Definition at line 5082 of file acl.c.
References AUTHNAME, CStringGetDatum, ereport, errcode(), errmsg(), ERROR, GetSysCacheOid1, and OidIsValid.
Referenced by aclparse(), ATExecCmd(), check_hba(), createdb(), CreateRole(), CreateSchemaCommand(), CreateTableSpace(), ExecAlterDefaultPrivilegesStmt(), ExecAlterOwnerStmt(), ExecuteGrantStmt(), get_object_address_unqualified(), get_role_oid_or_public(), GetUserOidFromMapping(), GrantRole(), is_member(), pg_has_role_id_name(), pg_has_role_name(), pg_has_role_name_id(), pg_has_role_name_name(), ReassignOwnedObjects(), and roleNamesToIds().
{ Oid oid; oid = GetSysCacheOid1(AUTHNAME, CStringGetDatum(rolname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("role \"%s\" does not exist", rolname))); return oid; }
Acl* get_user_default_acl | ( | GrantObjectType | objtype, | |
Oid | ownerId, | |||
Oid | nsp_oid | |||
) |
Definition at line 5120 of file aclchk.c.
References ACL_OBJECT_FUNCTION, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_OBJECT_TYPE, acldefault(), aclequal(), aclitemsort(), aclmerge(), get_default_acl_internal(), InvalidOid, IsBootstrapProcessingMode, and NULL.
Referenced by heap_create_with_catalog(), ProcedureCreate(), and TypeCreate().
{ Acl *result; Acl *glob_acl; Acl *schema_acl; Acl *def_acl; char defaclobjtype; /* * Use NULL during bootstrap, since pg_default_acl probably isn't there * yet. */ if (IsBootstrapProcessingMode()) return NULL; /* Check if object type is supported in pg_default_acl */ switch (objtype) { case ACL_OBJECT_RELATION: defaclobjtype = DEFACLOBJ_RELATION; break; case ACL_OBJECT_SEQUENCE: defaclobjtype = DEFACLOBJ_SEQUENCE; break; case ACL_OBJECT_FUNCTION: defaclobjtype = DEFACLOBJ_FUNCTION; break; case ACL_OBJECT_TYPE: defaclobjtype = DEFACLOBJ_TYPE; break; default: return NULL; } /* Look up the relevant pg_default_acl entries */ glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype); schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype); /* Quick out if neither entry exists */ if (glob_acl == NULL && schema_acl == NULL) return NULL; /* We need to know the hard-wired default value, too */ def_acl = acldefault(objtype, ownerId); /* If there's no global entry, substitute the hard-wired default */ if (glob_acl == NULL) glob_acl = def_acl; /* Merge in any per-schema privileges */ result = aclmerge(glob_acl, schema_acl, ownerId); /* * For efficiency, we want to return NULL if the result equals default. * This requires sorting both arrays to get an accurate comparison. */ aclitemsort(result); aclitemsort(def_acl); if (aclequal(result, def_acl)) result = NULL; return result; }
Definition at line 5064 of file aclchk.c.
References AUTHOID, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by check_object_ownership(), and have_createrole_privilege().
{ bool result = false; HeapTuple utup; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; utup = SearchSysCache1(AUTHOID, ObjectIdGetDatum(roleid)); if (HeapTupleIsValid(utup)) { result = ((Form_pg_authid) GETSTRUCT(utup))->rolcreaterole; ReleaseSysCache(utup); } return result; }
Definition at line 4825 of file acl.c.
References list_member_oid(), roles_has_privs_of(), and superuser_arg().
Referenced by aclmask(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), DropOwnedObjects(), pg_class_ownercheck(), pg_collation_ownercheck(), pg_conversion_ownercheck(), pg_database_ownercheck(), pg_event_trigger_ownercheck(), pg_extension_ownercheck(), pg_foreign_data_wrapper_ownercheck(), pg_foreign_server_ownercheck(), pg_language_ownercheck(), pg_largeobject_ownercheck(), pg_namespace_ownercheck(), pg_opclass_ownercheck(), pg_oper_ownercheck(), pg_opfamily_ownercheck(), pg_proc_ownercheck(), pg_role_aclcheck(), pg_tablespace_ownercheck(), pg_ts_config_ownercheck(), pg_ts_dict_ownercheck(), pg_type_ownercheck(), and ReassignOwnedObjects().
{ /* Fast path for simple case */ if (member == role) return true; /* Superusers have every privilege, so are part of every role */ if (superuser_arg(member)) return true; /* * Find all the roles that member has the privileges of, including * multi-level recursion, then see if target role is any one of them. */ return list_member_oid(roles_has_privs_of(member), role); }
Datum hash_aclitem | ( | PG_FUNCTION_ARGS | ) |
Definition at line 712 of file acl.c.
References AclItem::ai_grantee, AclItem::ai_grantor, AclItem::ai_privs, PG_GETARG_ACLITEM_P, and PG_RETURN_UINT32.
{ AclItem *a = PG_GETARG_ACLITEM_P(0); /* not very bright, but avoids any issue of padding in struct */ PG_RETURN_UINT32((uint32) (a->ai_privs + a->ai_grantee + a->ai_grantor)); }
void initialize_acl | ( | void | ) |
Definition at line 4606 of file acl.c.
References AUTHMEMROLEMEM, CacheRegisterSyscacheCallback(), IsBootstrapProcessingMode, and RoleMembershipCacheCallback().
Referenced by InitPostgres().
{ if (!IsBootstrapProcessingMode()) { /* * In normal mode, set a callback on any syscache invalidation of * pg_auth_members rows */ CacheRegisterSyscacheCallback(AUTHMEMROLEMEM, RoleMembershipCacheCallback, (Datum) 0); } }
Definition at line 4909 of file acl.c.
References AUTHMEMMEMROLE, GETSTRUCT, i, lfirst_oid, list_append_unique_oid(), list_free(), list_make1_oid, catclist::members, catclist::n_members, ObjectIdGetDatum, ReleaseSysCacheList, SearchSysCacheList1, superuser_arg(), and catctup::tuple.
Referenced by AddRoleMems(), DelRoleMems(), and pg_role_aclcheck().
{ bool result = false; List *roles_list; ListCell *l; /* Fast path for simple case */ if (member == role) return true; /* Superusers have every privilege, so are part of every role */ if (superuser_arg(member)) return true; /* * Find all the roles that member is a member of, including multi-level * recursion. We build a list in the same way that is_member_of_role does * to track visited and unvisited roles. */ roles_list = list_make1_oid(member); foreach(l, roles_list) { Oid memberid = lfirst_oid(l); CatCList *memlist; int i; /* Find roles that memberid is directly a member of */ memlist = SearchSysCacheList1(AUTHMEMMEMROLE, ObjectIdGetDatum(memberid)); for (i = 0; i < memlist->n_members; i++) { HeapTuple tup = &memlist->members[i]->tuple; Oid otherid = ((Form_pg_auth_members) GETSTRUCT(tup))->roleid; if (otherid == role && ((Form_pg_auth_members) GETSTRUCT(tup))->admin_option) { /* Found what we came for, so can stop searching */ result = true; break; } roles_list = list_append_unique_oid(roles_list, otherid); } ReleaseSysCacheList(memlist); if (result) break; } list_free(roles_list); return result; }
Definition at line 4849 of file acl.c.
References list_member_oid(), roles_is_member_of(), and superuser_arg().
Referenced by check_is_member_of_role(), check_role(), and pg_role_aclcheck().
{ /* Fast path for simple case */ if (member == role) return true; /* Superusers have every privilege, so are part of every role */ if (superuser_arg(member)) return true; /* * Find all the roles that member is a member of, including multi-level * recursion, then see if target role is any one of them. */ return list_member_oid(roles_is_member_of(member), role); }
Definition at line 4887 of file acl.c.
References list_member_oid(), and roles_is_member_of().
Referenced by AddRoleMems(), and is_member().
{ /* Fast path for simple case */ if (member == role) return true; /* * Find all the roles that member is a member of, including multi-level * recursion, then see if target role is any one of them. */ return list_member_oid(roles_is_member_of(member), role); }
Acl* make_empty_acl | ( | void | ) |
Definition at line 397 of file acl.c.
References allocacl().
Referenced by SetDefaultACL().
{ return allocacl(0); }
Datum makeaclitem | ( | PG_FUNCTION_ARGS | ) |
Definition at line 1575 of file acl.c.
References ACL_NO_RIGHTS, ACLITEM_SET_PRIVS_GOPTIONS, AclItem::ai_grantee, AclItem::ai_grantor, convert_priv_string(), palloc(), PG_GETARG_BOOL, PG_GETARG_OID, PG_GETARG_TEXT_P, and PG_RETURN_ACLITEM_P.
{ Oid grantee = PG_GETARG_OID(0); Oid grantor = PG_GETARG_OID(1); text *privtext = PG_GETARG_TEXT_P(2); bool goption = PG_GETARG_BOOL(3); AclItem *result; AclMode priv; priv = convert_priv_string(privtext); result = (AclItem *) palloc(sizeof(AclItem)); result->ai_grantee = grantee; result->ai_grantor = grantor; ACLITEM_SET_PRIVS_GOPTIONS(*result, priv, (goption ? priv : ACL_NO_RIGHTS)); PG_RETURN_ACLITEM_P(result); }
AclResult pg_attribute_aclcheck | ( | Oid | table_oid, | |
AttrNumber | attnum, | |||
Oid | roleid, | |||
AclMode | mode | |||
) |
Definition at line 4280 of file aclchk.c.
References ACLMASK_ANY, and pg_attribute_aclmask().
Referenced by checkFkeyPermissions(), column_privilege_check(), and ExecCheckRTEPerms().
{ if (pg_attribute_aclmask(table_oid, attnum, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclResult pg_attribute_aclcheck_all | ( | Oid | table_oid, | |
Oid | roleid, | |||
AclMode | mode, | |||
AclMaskHow | how | |||
) |
Definition at line 4309 of file aclchk.c.
References ACLMASK_ALL, ACLMASK_ANY, Anum_pg_attribute_attacl, ATTNUM, GETSTRUCT, heap_attisnull(), HeapTupleIsValid, Int16GetDatum, ObjectIdGetDatum, pg_attribute_aclmask(), ReleaseSysCache(), RELOID, SearchSysCache1, and SearchSysCache2.
Referenced by ExecCheckRTEPerms(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), has_any_column_privilege_name_id(), and has_any_column_privilege_name_name().
{ AclResult result; HeapTuple classTuple; Form_pg_class classForm; AttrNumber nattrs; AttrNumber curr_att; /* * Must fetch pg_class row to check number of attributes. As in * pg_attribute_aclmask, we prefer to return "no privileges" instead of * throwing an error if we get any unexpected lookup errors. */ classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid)); if (!HeapTupleIsValid(classTuple)) return ACLCHECK_NO_PRIV; classForm = (Form_pg_class) GETSTRUCT(classTuple); nattrs = classForm->relnatts; ReleaseSysCache(classTuple); /* * Initialize result in case there are no non-dropped columns. We want to * report failure in such cases for either value of 'how'. */ result = ACLCHECK_NO_PRIV; for (curr_att = 1; curr_att <= nattrs; curr_att++) { HeapTuple attTuple; AclMode attmask; attTuple = SearchSysCache2(ATTNUM, ObjectIdGetDatum(table_oid), Int16GetDatum(curr_att)); if (!HeapTupleIsValid(attTuple)) continue; /* ignore dropped columns */ if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped) { ReleaseSysCache(attTuple); continue; } /* * Here we hard-wire knowledge that the default ACL for a column * grants no privileges, so that we can fall out quickly in the very * common case where attacl is null. */ if (heap_attisnull(attTuple, Anum_pg_attribute_attacl)) attmask = 0; else attmask = pg_attribute_aclmask(table_oid, curr_att, roleid, mode, ACLMASK_ANY); ReleaseSysCache(attTuple); if (attmask != 0) { result = ACLCHECK_OK; if (how == ACLMASK_ANY) break; /* succeed on any success */ } else { result = ACLCHECK_NO_PRIV; if (how == ACLMASK_ALL) break; /* fail on any failure */ } } return result; }
AclMode pg_attribute_aclmask | ( | Oid | table_oid, | |
AttrNumber | attnum, | |||
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 3516 of file aclchk.c.
References aclmask(), Anum_pg_attribute_attacl, ATTNUM, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, Int16GetDatum, ObjectIdGetDatum, pfree(), ReleaseSysCache(), RELOID, SearchSysCache1, SearchSysCache2, and SysCacheGetAttr().
Referenced by pg_aclmask(), pg_attribute_aclcheck(), and pg_attribute_aclcheck_all().
{ AclMode result; HeapTuple classTuple; HeapTuple attTuple; Form_pg_class classForm; Form_pg_attribute attributeForm; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* * First, get the column's ACL from its pg_attribute entry */ attTuple = SearchSysCache2(ATTNUM, ObjectIdGetDatum(table_oid), Int16GetDatum(attnum)); if (!HeapTupleIsValid(attTuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("attribute %d of relation with OID %u does not exist", attnum, table_oid))); attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple); /* Throw error on dropped columns, too */ if (attributeForm->attisdropped) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("attribute %d of relation with OID %u does not exist", attnum, table_oid))); aclDatum = SysCacheGetAttr(ATTNUM, attTuple, Anum_pg_attribute_attacl, &isNull); /* * Here we hard-wire knowledge that the default ACL for a column grants no * privileges, so that we can fall out quickly in the very common case * where attacl is null. */ if (isNull) { ReleaseSysCache(attTuple); return 0; } /* * Must get the relation's ownerId from pg_class. Since we already found * a pg_attribute entry, the only likely reason for this to fail is that a * concurrent DROP of the relation committed since then (which could only * happen if we don't have lock on the relation). We prefer to report "no * privileges" rather than failing in such a case, so as to avoid unwanted * failures in has_column_privilege() tests. */ classTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid)); if (!HeapTupleIsValid(classTuple)) { ReleaseSysCache(attTuple); return 0; } classForm = (Form_pg_class) GETSTRUCT(classTuple); ownerId = classForm->relowner; ReleaseSysCache(classTuple); /* detoast column's ACL if necessary */ acl = DatumGetAclP(aclDatum); result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(attTuple); return result; }
Definition at line 4394 of file aclchk.c.
References ACLMASK_ANY, and pg_class_aclmask().
Referenced by checkFkeyPermissions(), column_privilege_check(), CreateTrigger(), currtid_byrelname(), currtid_byreloid(), currval_oid(), do_setval(), get_rel_from_relname(), has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), has_any_column_privilege_name_id(), has_any_column_privilege_name_name(), has_sequence_privilege_id(), has_sequence_privilege_id_id(), has_sequence_privilege_id_name(), has_sequence_privilege_name(), has_sequence_privilege_name_id(), has_sequence_privilege_name_name(), has_table_privilege_id(), has_table_privilege_id_id(), has_table_privilege_id_name(), has_table_privilege_name(), has_table_privilege_name_id(), has_table_privilege_name_name(), lastval(), LockTableAclCheck(), nextval_internal(), pg_sequence_parameters(), pgrowlocks(), transformTableLikeClause(), and truncate_check_rel().
{ if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_class_aclmask | ( | Oid | table_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 3601 of file aclchk.c.
References ACL_DELETE, ACL_INSERT, ACL_OBJECT_RELATION, ACL_OBJECT_SEQUENCE, ACL_TRUNCATE, ACL_UPDATE, ACL_USAGE, acldefault(), aclmask(), allowSystemTableMods, Anum_pg_class_relacl, DatumGetAclP, DatumGetPointer, DEBUG2, elog, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_rolcatupdate(), HeapTupleIsValid, IsSystemClass(), ObjectIdGetDatum, pfree(), ReleaseSysCache(), RELKIND_SEQUENCE, RELKIND_VIEW, RELOID, SearchSysCache1, superuser_arg(), and SysCacheGetAttr().
Referenced by ExecCheckRTEPerms(), pg_aclmask(), and pg_class_aclcheck().
{ AclMode result; HeapTuple tuple; Form_pg_class classForm; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* * Must get the relation's tuple from pg_class */ tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(table_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation with OID %u does not exist", table_oid))); classForm = (Form_pg_class) GETSTRUCT(tuple); /* * Deny anyone permission to update a system catalog unless * pg_authid.rolcatupdate is set. (This is to let superusers protect * themselves from themselves.) Also allow it if allowSystemTableMods. * * As of 7.4 we have some updatable system views; those shouldn't be * protected in this way. Assume the view rules can take care of * themselves. ACL_USAGE is if we ever have system sequences. */ if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) && IsSystemClass(classForm) && classForm->relkind != RELKIND_VIEW && !has_rolcatupdate(roleid) && !allowSystemTableMods) { #ifdef ACLDEBUG elog(DEBUG2, "permission denied for system catalog update"); #endif mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE); } /* * Otherwise, superusers bypass all permission-checking. */ if (superuser_arg(roleid)) { #ifdef ACLDEBUG elog(DEBUG2, "OID %u is superuser, home free", roleid); #endif ReleaseSysCache(tuple); return mask; } /* * Normal case: get the relation's ACL from pg_class */ ownerId = classForm->relowner; aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ switch (classForm->relkind) { case RELKIND_SEQUENCE: acl = acldefault(ACL_OBJECT_SEQUENCE, ownerId); break; default: acl = acldefault(ACL_OBJECT_RELATION, ownerId); break; } aclDatum = (Datum) 0; } else { /* detoast rel's ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4518 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), RELOID, SearchSysCache1, and superuser_arg().
Referenced by AlterSequence(), analyze_rel(), ATExecChangeOwner(), ATPrepSetStatistics(), ATSimplePermissions(), check_object_ownership(), CheckRelationOwnership(), cluster_rel(), DefineQueryRewrite(), EnableDisableRule(), ExecuteTruncate(), get_tables_to_cluster(), MergeAttributes(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackOwnsTable(), RangeVarGetAndCheckCreationNamespace(), renameatt_check(), and vacuum_rel().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(class_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("relation with OID %u does not exist", class_oid))); ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4962 of file aclchk.c.
References COLLOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by check_object_ownership().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(COLLOID, ObjectIdGetDatum(coll_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("collation with OID %u does not exist", coll_oid))); ownerId = ((Form_pg_collation) GETSTRUCT(tuple))->collowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4988 of file aclchk.c.
References CONVOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by check_object_ownership().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(CONVOID, ObjectIdGetDatum(conv_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("conversion with OID %u does not exist", conv_oid))); ownerId = ((Form_pg_conversion) GETSTRUCT(tuple))->conowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4406 of file aclchk.c.
References ACLMASK_ANY, and pg_database_aclmask().
Referenced by AlterSchemaOwner_internal(), calculate_database_size(), CheckMyDatabase(), CreateSchemaCommand(), has_database_privilege_id(), has_database_privilege_id_id(), has_database_privilege_id_name(), has_database_privilege_name(), has_database_privilege_name_id(), has_database_privilege_name_name(), InitTempTableNamespace(), pg_namespace_aclmask(), and RenameSchema().
{ if (pg_database_aclmask(db_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_database_aclmask | ( | Oid | db_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 3698 of file aclchk.c.
References ACL_OBJECT_DATABASE, acldefault(), aclmask(), Anum_pg_database_datacl, DATABASEOID, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1, superuser_arg(), and SysCacheGetAttr().
Referenced by pg_aclmask(), and pg_database_aclcheck().
{ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * Get the database's ACL from pg_database */ tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database with OID %u does not exist", db_oid))); ownerId = ((Form_pg_database) GETSTRUCT(tuple))->datdba; aclDatum = SysCacheGetAttr(DATABASEOID, tuple, Anum_pg_database_datacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_DATABASE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4936 of file aclchk.c.
References DATABASEOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseSet(), AlterRoleSet(), analyze_rel(), check_object_ownership(), createdb(), CreateProceduralLanguage(), dropdb(), movedb(), ReindexDatabase(), RenameDatabase(), and vacuum_rel().
{ HeapTuple tuple; Oid dba; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(db_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database with OID %u does not exist", db_oid))); dba = ((Form_pg_database) GETSTRUCT(tuple))->datdba; ReleaseSysCache(tuple); return has_privs_of_role(roleid, dba); }
Definition at line 4909 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, EVENTTRIGGEROID, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by AlterEventTrigger(), AlterEventTriggerOwner_internal(), and check_object_ownership().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(et_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("event trigger with OID %u does not exist", et_oid))); ownerId = ((Form_pg_event_trigger) GETSTRUCT(tuple))->evtowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 5014 of file aclchk.c.
References AccessShareLock, BTEqualStrategyNumber, ereport, errcode(), errmsg(), ERROR, ExtensionOidIndexId, ExtensionRelationId, GETSTRUCT, has_privs_of_role(), heap_close, heap_open(), HeapTupleIsValid, ObjectIdAttributeNumber, ObjectIdGetDatum, ScanKeyInit(), SnapshotNow, superuser_arg(), systable_beginscan(), systable_endscan(), and systable_getnext().
Referenced by AlterExtensionNamespace(), check_object_ownership(), ExecAlterExtensionContentsStmt(), and ExecAlterExtensionStmt().
{ Relation pg_extension; ScanKeyData entry[1]; SysScanDesc scan; HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; /* There's no syscache for pg_extension, so do it the hard way */ pg_extension = heap_open(ExtensionRelationId, AccessShareLock); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ext_oid)); scan = systable_beginscan(pg_extension, ExtensionOidIndexId, true, SnapshotNow, 1, entry); tuple = systable_getnext(scan); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("extension with OID %u does not exist", ext_oid))); ownerId = ((Form_pg_extension) GETSTRUCT(tuple))->extowner; systable_endscan(scan); heap_close(pg_extension, AccessShareLock); return has_privs_of_role(roleid, ownerId); }
Definition at line 4481 of file aclchk.c.
References ACLMASK_ANY, and pg_foreign_data_wrapper_aclmask().
Referenced by AlterForeignServerOwner_internal(), CreateForeignServer(), has_foreign_data_wrapper_privilege_id(), has_foreign_data_wrapper_privilege_id_id(), has_foreign_data_wrapper_privilege_id_name(), has_foreign_data_wrapper_privilege_name(), has_foreign_data_wrapper_privilege_name_id(), and has_foreign_data_wrapper_privilege_name_name().
{ if (pg_foreign_data_wrapper_aclmask(fdw_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_foreign_data_wrapper_aclmask | ( | Oid | fdw_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 4078 of file aclchk.c.
References ACL_OBJECT_FDW, acldefault(), aclmask(), Anum_pg_foreign_data_wrapper_fdwacl, DatumGetAclP, DatumGetPointer, ereport, errmsg(), ERROR, FOREIGNDATAWRAPPEROID, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1, superuser_arg(), and SysCacheGetAttr().
Referenced by pg_aclmask(), and pg_foreign_data_wrapper_aclcheck().
{ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; Form_pg_foreign_data_wrapper fdwForm; /* Bypass permission checks for superusers */ if (superuser_arg(roleid)) return mask; /* * Must get the FDW's tuple from pg_foreign_data_wrapper */ tuple = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdw_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errmsg("foreign-data wrapper with OID %u does not exist", fdw_oid))); fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tuple); /* * Normal case: get the FDW's ACL from pg_foreign_data_wrapper */ ownerId = fdwForm->fdwowner; aclDatum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID, tuple, Anum_pg_foreign_data_wrapper_fdwacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_FDW, ownerId); aclDatum = (Datum) 0; } else { /* detoast rel's ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4855 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, FOREIGNDATAWRAPPEROID, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by check_object_ownership().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(srv_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("foreign-data wrapper with OID %u does not exist", srv_oid))); ownerId = ((Form_pg_foreign_data_wrapper) GETSTRUCT(tuple))->fdwowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4494 of file aclchk.c.
References ACLMASK_ANY, and pg_foreign_server_aclmask().
Referenced by CreateForeignTable(), get_connect_string(), has_server_privilege_id(), has_server_privilege_id_id(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_id(), has_server_privilege_name_name(), and user_mapping_ddl_aclcheck().
{ if (pg_foreign_server_aclmask(srv_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_foreign_server_aclmask | ( | Oid | srv_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 4139 of file aclchk.c.
References ACL_OBJECT_FOREIGN_SERVER, acldefault(), aclmask(), Anum_pg_foreign_server_srvacl, DatumGetAclP, DatumGetPointer, ereport, errmsg(), ERROR, FOREIGNSERVEROID, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1, superuser_arg(), and SysCacheGetAttr().
Referenced by pg_aclmask(), and pg_foreign_server_aclcheck().
{ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; Form_pg_foreign_server srvForm; /* Bypass permission checks for superusers */ if (superuser_arg(roleid)) return mask; /* * Must get the FDW's tuple from pg_foreign_data_wrapper */ tuple = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(srv_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errmsg("foreign server with OID %u does not exist", srv_oid))); srvForm = (Form_pg_foreign_server) GETSTRUCT(tuple); /* * Normal case: get the foreign server's ACL from pg_foreign_server */ ownerId = srvForm->srvowner; aclDatum = SysCacheGetAttr(FOREIGNSERVEROID, tuple, Anum_pg_foreign_server_srvacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_FOREIGN_SERVER, ownerId); aclDatum = (Datum) 0; } else { /* detoast rel's ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4882 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, FOREIGNSERVEROID, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by AlterForeignServer(), AlterForeignServerOwner_internal(), check_object_ownership(), and user_mapping_ddl_aclcheck().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(srv_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("foreign server with OID %u does not exist", srv_oid))); ownerId = ((Form_pg_foreign_server) GETSTRUCT(tuple))->srvowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4430 of file aclchk.c.
References ACLMASK_ANY, and pg_language_aclmask().
Referenced by CreateFunction(), ExecuteDoStmt(), has_language_privilege_id(), has_language_privilege_id_id(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_id(), and has_language_privilege_name_name().
{ if (pg_language_aclmask(lang_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_language_aclmask | ( | Oid | lang_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 3806 of file aclchk.c.
References ACL_OBJECT_LANGUAGE, acldefault(), aclmask(), Anum_pg_language_lanacl, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, LANGOID, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1, superuser_arg(), and SysCacheGetAttr().
Referenced by pg_aclmask(), and pg_language_aclcheck().
{ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * Get the language's ACL from pg_language */ tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lang_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("language with OID %u does not exist", lang_oid))); ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner; aclDatum = SysCacheGetAttr(LANGOID, tuple, Anum_pg_language_lanacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_LANGUAGE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4622 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, LANGOID, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by check_object_ownership(), and create_proc_lang().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(LANGOID, ObjectIdGetDatum(lan_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("language with OID %u does not exist", lan_oid))); ownerId = ((Form_pg_language) GETSTRUCT(tuple))->lanowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
AclResult pg_largeobject_aclcheck_snapshot | ( | Oid | lang_oid, | |
Oid | roleid, | |||
AclMode | mode, | |||
Snapshot | snapshot | |||
) |
Definition at line 4442 of file aclchk.c.
References ACLMASK_ANY, and pg_largeobject_aclmask_snapshot().
Referenced by lo_read(), lo_truncate_internal(), and lo_write().
{ if (pg_largeobject_aclmask_snapshot(lobj_oid, roleid, mode, ACLMASK_ANY, snapshot) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_largeobject_aclmask_snapshot | ( | Oid | lobj_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how, | |||
Snapshot | snapshot | |||
) |
Definition at line 3866 of file aclchk.c.
References AccessShareLock, ACL_OBJECT_LARGEOBJECT, acldefault(), aclmask(), Anum_pg_largeobject_metadata_lomacl, BTEqualStrategyNumber, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, heap_close, heap_getattr, heap_open(), HeapTupleIsValid, LargeObjectMetadataOidIndexId, LargeObjectMetadataRelationId, ObjectIdAttributeNumber, ObjectIdGetDatum, pfree(), RelationGetDescr, ScanKeyInit(), superuser_arg(), systable_beginscan(), systable_endscan(), and systable_getnext().
Referenced by pg_aclmask(), and pg_largeobject_aclcheck_snapshot().
{ AclMode result; Relation pg_lo_meta; ScanKeyData entry[1]; SysScanDesc scan; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * Get the largeobject's ACL from pg_language_metadata */ pg_lo_meta = heap_open(LargeObjectMetadataRelationId, AccessShareLock); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(lobj_oid)); scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, snapshot, 1, entry); tuple = systable_getnext(scan); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("large object %u does not exist", lobj_oid))); ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner; aclDatum = heap_getattr(tuple, Anum_pg_largeobject_metadata_lomacl, RelationGetDescr(pg_lo_meta), &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_LARGEOBJECT, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); systable_endscan(scan); heap_close(pg_lo_meta, AccessShareLock); return result; }
Definition at line 4651 of file aclchk.c.
References AccessShareLock, BTEqualStrategyNumber, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), heap_close, heap_open(), HeapTupleIsValid, LargeObjectMetadataOidIndexId, LargeObjectMetadataRelationId, ObjectIdAttributeNumber, ObjectIdGetDatum, ScanKeyInit(), SnapshotNow, superuser_arg(), systable_beginscan(), systable_endscan(), and systable_getnext().
Referenced by check_object_ownership(), and lo_unlink().
{ Relation pg_lo_meta; ScanKeyData entry[1]; SysScanDesc scan; HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; /* There's no syscache for pg_largeobject_metadata */ pg_lo_meta = heap_open(LargeObjectMetadataRelationId, AccessShareLock); ScanKeyInit(&entry[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(lobj_oid)); scan = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, SnapshotNow, 1, entry); tuple = systable_getnext(scan); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("large object %u does not exist", lobj_oid))); ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner; systable_endscan(scan); heap_close(pg_lo_meta, AccessShareLock); return has_privs_of_role(roleid, ownerId); }
Definition at line 4456 of file aclchk.c.
References ACLMASK_ANY, and pg_namespace_aclmask().
Referenced by AlterExtensionNamespace(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterTypeOwner(), ATExecChangeOwner(), compute_return_type(), CreateConversionCommand(), CreateFunction(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), get_other_operator(), HandleFunctionRequest(), has_schema_privilege_id(), has_schema_privilege_id_id(), has_schema_privilege_id_name(), has_schema_privilege_name(), has_schema_privilege_name_id(), has_schema_privilege_name_name(), LookupCreationNamespace(), LookupExplicitNamespace(), RangeVarCallbackForAlterRelation(), RangeVarGetAndCheckCreationNamespace(), recomputeNamespacePath(), and SetDefaultACLsInSchemas().
{ if (pg_namespace_aclmask(nsp_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_namespace_aclmask | ( | Oid | nsp_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 3939 of file aclchk.c.
References ACL_CREATE_TEMP, ACL_OBJECT_NAMESPACE, ACLCHECK_OK, acldefault(), aclmask(), Anum_pg_namespace_nspacl, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, isTempNamespace(), MyDatabaseId, NAMESPACEOID, ObjectIdGetDatum, pfree(), pg_database_aclcheck(), ReleaseSysCache(), SearchSysCache1, superuser_arg(), and SysCacheGetAttr().
Referenced by pg_aclmask(), and pg_namespace_aclcheck().
{ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * If we have been assigned this namespace as a temp namespace, check to * make sure we have CREATE TEMP permission on the database, and if so act * as though we have all standard (but not GRANT OPTION) permissions on * the namespace. If we don't have CREATE TEMP, act as though we have * only USAGE (and not CREATE) rights. * * This may seem redundant given the check in InitTempTableNamespace, but * it really isn't since current user ID may have changed since then. The * upshot of this behavior is that a SECURITY DEFINER function can create * temp tables that can then be accessed (if permission is granted) by * code in the same session that doesn't have permissions to create temp * tables. * * XXX Would it be safe to ereport a special error message as * InitTempTableNamespace does? Returning zero here means we'll get a * generic "permission denied for schema pg_temp_N" message, which is not * remarkably user-friendly. */ if (isTempNamespace(nsp_oid)) { if (pg_database_aclcheck(MyDatabaseId, roleid, ACL_CREATE_TEMP) == ACLCHECK_OK) return mask & ACL_ALL_RIGHTS_NAMESPACE; else return mask & ACL_USAGE; } /* * Get the schema's ACL from pg_namespace */ tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema with OID %u does not exist", nsp_oid))); ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; aclDatum = SysCacheGetAttr(NAMESPACEOID, tuple, Anum_pg_namespace_nspacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_NAMESPACE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4694 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, NAMESPACEOID, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by AlterSchemaOwner_internal(), check_object_ownership(), RangeVarCallbackForDropRelation(), RemoveObjects(), and RenameSchema().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(nsp_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema with OID %u does not exist", nsp_oid))); ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4747 of file aclchk.c.
References CLAOID, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by check_object_ownership().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opc_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator class with OID %u does not exist", opc_oid))); ownerId = ((Form_pg_opclass) GETSTRUCT(tuple))->opcowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4570 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, OPEROID, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by AlterOpFamilyAdd(), check_object_ownership(), DefineOpClass(), and OperatorCreate().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(OPEROID, ObjectIdGetDatum(oper_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("operator with OID %u does not exist", oper_oid))); ownerId = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4774 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, OPFAMILYOID, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by check_object_ownership().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opf_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("operator family with OID %u does not exist", opf_oid))); ownerId = ((Form_pg_opfamily) GETSTRUCT(tuple))->opfowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4418 of file aclchk.c.
References ACLMASK_ANY, and pg_proc_aclmask().
Referenced by CreateConversionCommand(), CreateTrigger(), DefineOperator(), ExecEvalArrayCoerceExpr(), ExecInitAgg(), ExecInitWindowAgg(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), HandleFunctionRequest(), has_function_privilege_id(), has_function_privilege_id_id(), has_function_privilege_id_name(), has_function_privilege_name(), has_function_privilege_name_id(), has_function_privilege_name_name(), init_fcache(), initialize_peragg(), inline_function(), inline_set_returning_function(), and lookup_agg_function().
{ if (pg_proc_aclmask(proc_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_proc_aclmask | ( | Oid | proc_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 3752 of file aclchk.c.
References ACL_OBJECT_FUNCTION, acldefault(), aclmask(), Anum_pg_proc_proacl, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, pfree(), PROCOID, ReleaseSysCache(), SearchSysCache1, superuser_arg(), and SysCacheGetAttr().
Referenced by pg_aclmask(), and pg_proc_aclcheck().
{ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * Get the function's ACL from pg_proc */ tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(proc_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("function with OID %u does not exist", proc_oid))); ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; aclDatum = SysCacheGetAttr(PROCOID, tuple, Anum_pg_proc_proacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_FUNCTION, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4596 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, PROCOID, ReleaseSysCache(), SearchSysCache1, and superuser_arg().
Referenced by AlterFunction(), AlterOpFamilyAdd(), check_object_ownership(), DefineOpClass(), DefineType(), and ProcedureCreate().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(proc_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), errmsg("function with OID %u does not exist", proc_oid))); ownerId = ((Form_pg_proc) GETSTRUCT(tuple))->proowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4468 of file aclchk.c.
References ACLMASK_ANY, and pg_tablespace_aclmask().
Referenced by ATPrepSetTableSpace(), calculate_tablespace_size(), check_temp_tablespaces(), createdb(), DefineIndex(), DefineRelation(), has_tablespace_privilege_id(), has_tablespace_privilege_id_id(), has_tablespace_privilege_id_name(), has_tablespace_privilege_name(), has_tablespace_privilege_name_id(), has_tablespace_privilege_name_name(), movedb(), and PrepareTempTablespaces().
{ if (pg_tablespace_aclmask(spc_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_tablespace_aclmask | ( | Oid | spc_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 4021 of file aclchk.c.
References ACL_OBJECT_TABLESPACE, acldefault(), aclmask(), Anum_pg_tablespace_spcacl, DatumGetAclP, DatumGetPointer, ereport, errcode(), errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1, superuser_arg(), SysCacheGetAttr(), and TABLESPACEOID.
Referenced by pg_aclmask(), and pg_tablespace_aclcheck().
{ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return mask; /* * Get the tablespace's ACL from pg_tablespace */ tuple = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spc_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("tablespace with OID %u does not exist", spc_oid))); ownerId = ((Form_pg_tablespace) GETSTRUCT(tuple))->spcowner; aclDatum = SysCacheGetAttr(TABLESPACEOID, tuple, Anum_pg_tablespace_spcacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_TABLESPACE, ownerId); aclDatum = (Datum) 0; } else { /* detoast ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4720 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, superuser_arg(), and TABLESPACEOID.
Referenced by AlterTableSpaceOptions(), check_object_ownership(), DropTableSpace(), and RenameTableSpace().
{ HeapTuple spctuple; Oid spcowner; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; /* Search syscache for pg_tablespace */ spctuple = SearchSysCache1(TABLESPACEOID, ObjectIdGetDatum(spc_oid)); if (!HeapTupleIsValid(spctuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("tablespace with OID %u does not exist", spc_oid))); spcowner = ((Form_pg_tablespace) GETSTRUCT(spctuple))->spcowner; ReleaseSysCache(spctuple); return has_privs_of_role(roleid, spcowner); }
Definition at line 4828 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, superuser_arg(), and TSCONFIGOID.
Referenced by AlterTSConfiguration(), and check_object_ownership().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfg_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("text search configuration with OID %u does not exist", cfg_oid))); ownerId = ((Form_pg_ts_config) GETSTRUCT(tuple))->cfgowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4801 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, superuser_arg(), and TSDICTOID.
Referenced by AlterTSDictionary(), and check_object_ownership().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dict_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("text search dictionary with OID %u does not exist", dict_oid))); ownerId = ((Form_pg_ts_dict) GETSTRUCT(tuple))->dictowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
Definition at line 4506 of file aclchk.c.
References ACLMASK_ANY, and pg_type_aclmask().
Referenced by AggregateCreate(), ATExecAddColumn(), ATPrepAlterColumnType(), BuildDescForRelation(), compute_return_type(), CreateCast(), DefineDomain(), DefineOperator(), DefineRelation(), examine_parameter_list(), has_type_privilege_id(), has_type_privilege_id_id(), has_type_privilege_id_name(), has_type_privilege_name(), has_type_privilege_name_id(), has_type_privilege_name_name(), and transformTableLikeClause().
{ if (pg_type_aclmask(type_oid, roleid, mode, ACLMASK_ANY) != 0) return ACLCHECK_OK; else return ACLCHECK_NO_PRIV; }
AclMode pg_type_aclmask | ( | Oid | type_oid, | |
Oid | roleid, | |||
AclMode | mask, | |||
AclMaskHow | how | |||
) |
Definition at line 4199 of file aclchk.c.
References ACL_OBJECT_TYPE, acldefault(), aclmask(), Anum_pg_type_typacl, DatumGetAclP, DatumGetPointer, ereport, errmsg(), ERROR, GETSTRUCT, HeapTupleIsValid, ObjectIdGetDatum, pfree(), ReleaseSysCache(), SearchSysCache1, superuser_arg(), SysCacheGetAttr(), and TYPEOID.
Referenced by pg_aclmask(), and pg_type_aclcheck().
{ AclMode result; HeapTuple tuple; Datum aclDatum; bool isNull; Acl *acl; Oid ownerId; Form_pg_type typeForm; /* Bypass permission checks for superusers */ if (superuser_arg(roleid)) return mask; /* * Must get the type's tuple from pg_type */ tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errmsg("type with OID %u does not exist", type_oid))); typeForm = (Form_pg_type) GETSTRUCT(tuple); /* "True" array types don't manage permissions of their own */ if (typeForm->typelem != 0 && typeForm->typlen == -1) { Oid elttype_oid = typeForm->typelem; ReleaseSysCache(tuple); tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(elttype_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errmsg("type with OID %u does not exist", type_oid))); typeForm = (Form_pg_type) GETSTRUCT(tuple); } /* * Normal case: get the type's ACL from pg_type */ ownerId = typeForm->typowner; aclDatum = SysCacheGetAttr(TYPEOID, tuple, Anum_pg_type_typacl, &isNull); if (isNull) { /* No ACL, so build default ACL */ acl = acldefault(ACL_OBJECT_TYPE, ownerId); aclDatum = (Datum) 0; } else { /* detoast rel's ACL if necessary */ acl = DatumGetAclP(aclDatum); } result = aclmask(acl, roleid, ownerId, mask, how); /* if we have a detoasted copy, free it */ if (acl && (Pointer) acl != DatumGetPointer(aclDatum)) pfree(acl); ReleaseSysCache(tuple); return result; }
Definition at line 4544 of file aclchk.c.
References ereport, errcode(), errmsg(), ERROR, GETSTRUCT, has_privs_of_role(), HeapTupleIsValid, ObjectIdGetDatum, ReleaseSysCache(), SearchSysCache1, superuser_arg(), and TYPEOID.
Referenced by AlterTypeNamespace_oid(), AlterTypeOwner(), check_object_ownership(), checkDomainOwner(), checkEnumOwner(), CreateCast(), DefineOpClass(), and RenameType().
{ HeapTuple tuple; Oid ownerId; /* Superusers bypass all permission checking. */ if (superuser_arg(roleid)) return true; tuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type_oid)); if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type with OID %u does not exist", type_oid))); ownerId = ((Form_pg_type) GETSTRUCT(tuple))->typowner; ReleaseSysCache(tuple); return has_privs_of_role(roleid, ownerId); }
void RemoveDefaultACLById | ( | Oid | defaclOid | ) |
Definition at line 1441 of file aclchk.c.
References BTEqualStrategyNumber, DefaultAclOidIndexId, DefaultAclRelationId, elog, ERROR, heap_close, heap_open(), HeapTupleIsValid, ObjectIdAttributeNumber, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), simple_heap_delete(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.
Referenced by doDeletion().
{ Relation rel; ScanKeyData skey[1]; SysScanDesc scan; HeapTuple tuple; rel = heap_open(DefaultAclRelationId, RowExclusiveLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(defaclOid)); scan = systable_beginscan(rel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey); tuple = systable_getnext(scan); if (!HeapTupleIsValid(tuple)) elog(ERROR, "could not find tuple for default ACL %u", defaclOid); simple_heap_delete(rel, &tuple->t_self); systable_endscan(scan); heap_close(rel, RowExclusiveLock); }
Definition at line 1316 of file aclchk.c.
References AccessShareLock, InternalGrant::all_privs, InternalDefaultACL::all_privs, InternalGrant::behavior, InternalDefaultACL::behavior, BTEqualStrategyNumber, InternalGrant::col_privs, DatabaseRelationId, DEFACLOBJ_FUNCTION, DEFACLOBJ_RELATION, DEFACLOBJ_SEQUENCE, DEFACLOBJ_TYPE, DefaultAclOidIndexId, DefaultAclRelationId, elog, ERROR, ExecGrantStmt_oids(), ForeignDataWrapperRelationId, ForeignServerRelationId, GETSTRUCT, InternalGrant::grant_option, InternalDefaultACL::grant_option, InternalGrant::grantees, InternalDefaultACL::grantees, heap_close, heap_open(), HeapTupleIsValid, InternalGrant::is_grant, InternalDefaultACL::is_grant, LanguageRelationId, LargeObjectRelationId, list_make1_oid, NamespaceRelationId, InternalDefaultACL::nspid, ObjectIdAttributeNumber, ObjectIdGetDatum, InternalGrant::objects, InternalGrant::objtype, InternalDefaultACL::objtype, InternalGrant::privileges, InternalDefaultACL::privileges, ProcedureRelationId, RelationRelationId, InternalDefaultACL::roleid, ScanKeyInit(), SetDefaultACL(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), TableSpaceRelationId, and TypeRelationId.
Referenced by shdepDropOwned().
{ if (classid == DefaultAclRelationId) { InternalDefaultACL iacls; Form_pg_default_acl pg_default_acl_tuple; Relation rel; ScanKeyData skey[1]; SysScanDesc scan; HeapTuple tuple; /* first fetch info needed by SetDefaultACL */ rel = heap_open(DefaultAclRelationId, AccessShareLock); ScanKeyInit(&skey[0], ObjectIdAttributeNumber, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objid)); scan = systable_beginscan(rel, DefaultAclOidIndexId, true, SnapshotNow, 1, skey); tuple = systable_getnext(scan); if (!HeapTupleIsValid(tuple)) elog(ERROR, "could not find tuple for default ACL %u", objid); pg_default_acl_tuple = (Form_pg_default_acl) GETSTRUCT(tuple); iacls.roleid = pg_default_acl_tuple->defaclrole; iacls.nspid = pg_default_acl_tuple->defaclnamespace; switch (pg_default_acl_tuple->defaclobjtype) { case DEFACLOBJ_RELATION: iacls.objtype = ACL_OBJECT_RELATION; break; case DEFACLOBJ_SEQUENCE: iacls.objtype = ACL_OBJECT_SEQUENCE; break; case DEFACLOBJ_FUNCTION: iacls.objtype = ACL_OBJECT_FUNCTION; break; case DEFACLOBJ_TYPE: iacls.objtype = ACL_OBJECT_TYPE; break; default: /* Shouldn't get here */ elog(ERROR, "unexpected default ACL type: %d", (int) pg_default_acl_tuple->defaclobjtype); break; } systable_endscan(scan); heap_close(rel, AccessShareLock); iacls.is_grant = false; iacls.all_privs = true; iacls.privileges = ACL_NO_RIGHTS; iacls.grantees = list_make1_oid(roleid); iacls.grant_option = false; iacls.behavior = DROP_CASCADE; /* Do it */ SetDefaultACL(&iacls); } else { InternalGrant istmt; switch (classid) { case RelationRelationId: /* it's OK to use RELATION for a sequence */ istmt.objtype = ACL_OBJECT_RELATION; break; case DatabaseRelationId: istmt.objtype = ACL_OBJECT_DATABASE; break; case TypeRelationId: istmt.objtype = ACL_OBJECT_TYPE; break; case ProcedureRelationId: istmt.objtype = ACL_OBJECT_FUNCTION; break; case LanguageRelationId: istmt.objtype = ACL_OBJECT_LANGUAGE; break; case LargeObjectRelationId: istmt.objtype = ACL_OBJECT_LARGEOBJECT; break; case NamespaceRelationId: istmt.objtype = ACL_OBJECT_NAMESPACE; break; case TableSpaceRelationId: istmt.objtype = ACL_OBJECT_TABLESPACE; break; case ForeignServerRelationId: istmt.objtype = ACL_OBJECT_FOREIGN_SERVER; break; case ForeignDataWrapperRelationId: istmt.objtype = ACL_OBJECT_FDW; break; default: elog(ERROR, "unexpected object class %u", classid); break; } istmt.is_grant = false; istmt.objects = list_make1_oid(objid); istmt.all_privs = true; istmt.privileges = ACL_NO_RIGHTS; istmt.col_privs = NIL; istmt.grantees = list_make1_oid(roleid); istmt.grant_option = false; istmt.behavior = DROP_CASCADE; ExecGrantStmt_oids(&istmt); } }
void select_best_grantor | ( | Oid | roleId, | |
AclMode | privileges, | |||
const Acl * | acl, | |||
Oid | ownerId, | |||
Oid * | grantorId, | |||
AclMode * | grantOptions | |||
) |
Definition at line 5007 of file acl.c.
References ACL_GRANT_OPTION_FOR, ACL_NO_RIGHTS, ACLMASK_ALL, aclmask_direct(), count_one_bits(), lfirst_oid, roles_has_privs_of(), and superuser_arg().
Referenced by ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), and ExecGrant_Type().
{ AclMode needed_goptions = ACL_GRANT_OPTION_FOR(privileges); List *roles_list; int nrights; ListCell *l; /* * The object owner is always treated as having all grant options, so if * roleId is the owner it's easy. Also, if roleId is a superuser it's * easy: superusers are implicitly members of every role, so they act as * the object owner. */ if (roleId == ownerId || superuser_arg(roleId)) { *grantorId = ownerId; *grantOptions = needed_goptions; return; } /* * Otherwise we have to do a careful search to see if roleId has the * privileges of any suitable role. Note: we can hang onto the result of * roles_has_privs_of() throughout this loop, because aclmask_direct() * doesn't query any role memberships. */ roles_list = roles_has_privs_of(roleId); /* initialize candidate result as default */ *grantorId = roleId; *grantOptions = ACL_NO_RIGHTS; nrights = 0; foreach(l, roles_list) { Oid otherrole = lfirst_oid(l); AclMode otherprivs; otherprivs = aclmask_direct(acl, otherrole, ownerId, needed_goptions, ACLMASK_ALL); if (otherprivs == needed_goptions) { /* Found a suitable grantor */ *grantorId = otherrole; *grantOptions = otherprivs; return; } /* * If it has just some of the needed privileges, remember best * candidate. */ if (otherprivs != ACL_NO_RIGHTS) { int nnewrights = count_one_bits(otherprivs); if (nnewrights > nrights) { *grantorId = otherrole; *grantOptions = otherprivs; nrights = nnewrights; } } } }