#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;
}
}
}
}
1.7.1