PostgreSQL Source Code git master
Loading...
Searching...
No Matches
aclchk.c File Reference
Include dependency graph for aclchk.c:

Go to the source code of this file.

Data Structures

struct  InternalDefaultACL
 

Functions

static void ExecGrantStmt_oids (InternalGrant *istmt)
 
static void ExecGrant_Relation (InternalGrant *istmt)
 
static void ExecGrant_common (InternalGrant *istmt, Oid classid, AclMode default_privs, void(*object_check)(InternalGrant *istmt, HeapTuple tuple))
 
static void ExecGrant_Language_check (InternalGrant *istmt, HeapTuple tuple)
 
static void ExecGrant_Largeobject (InternalGrant *istmt)
 
static void ExecGrant_Type_check (InternalGrant *istmt, HeapTuple tuple)
 
static void ExecGrant_Parameter (InternalGrant *istmt)
 
static void SetDefaultACLsInSchemas (InternalDefaultACL *iacls, List *nspnames)
 
static void SetDefaultACL (InternalDefaultACL *iacls)
 
static ListobjectNamesToOids (ObjectType objtype, List *objnames, bool is_grant)
 
static ListobjectsInSchemaToOids (ObjectType objtype, List *nspnames)
 
static ListgetRelationsInNamespace (Oid namespaceId, char relkind)
 
static void expand_col_privileges (List *colnames, Oid table_oid, AclMode this_privileges, AclMode *col_privileges, int num_col_privileges)
 
static void expand_all_col_privileges (Oid table_oid, Form_pg_class classForm, AclMode this_privileges, AclMode *col_privileges, int num_col_privileges)
 
static AclMode string_to_privilege (const char *privname)
 
static const charprivilege_to_string (AclMode privilege)
 
static AclMode restrict_and_check_grant (bool is_grant, AclMode avail_goptions, bool all_privs, AclMode privileges, Oid objectId, Oid grantorId, ObjectType objtype, const char *objname, AttrNumber att_number, const char *colname)
 
static AclMode pg_aclmask (ObjectType objtype, Oid object_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
 
static AclMode object_aclmask (Oid classid, Oid objectid, Oid roleid, AclMode mask, AclMaskHow how)
 
static AclMode object_aclmask_ext (Oid classid, Oid objectid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
 
static AclMode pg_attribute_aclmask (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
 
static AclMode pg_attribute_aclmask_ext (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
 
static AclMode pg_class_aclmask_ext (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
 
static AclMode pg_parameter_acl_aclmask (Oid acl_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
static AclMode pg_largeobject_aclmask_snapshot (Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
 
static AclMode pg_namespace_aclmask_ext (Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
 
static AclMode pg_type_aclmask_ext (Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
 
static void recordExtensionInitPriv (Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
 
static void recordExtensionInitPrivWorker (Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
 
static Aclmerge_acl_with_grant (Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, Oid grantorId, Oid ownerId)
 
void ExecuteGrantStmt (GrantStmt *stmt)
 
void ExecAlterDefaultPrivilegesStmt (ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
 
void RemoveRoleFromObjectACL (Oid roleid, Oid classid, Oid objid)
 
static void ExecGrant_Attribute (InternalGrant *istmt, Oid relOid, const char *relname, AttrNumber attnum, Oid ownerId, AclMode col_privileges, Relation attRelation, const Acl *old_rel_acl)
 
void aclcheck_error (AclResult aclerr, ObjectType objtype, const char *objectname)
 
void aclcheck_error_col (AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
 
void aclcheck_error_type (AclResult aclerr, Oid typeOid)
 
AclMode pg_class_aclmask (Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
 
static AclMode pg_parameter_aclmask (const char *name, Oid roleid, AclMode mask, AclMaskHow how)
 
AclResult object_aclcheck (Oid classid, Oid objectid, Oid roleid, AclMode mode)
 
AclResult object_aclcheck_ext (Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
 
AclResult pg_attribute_aclcheck_ext (Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_attribute_aclcheck_all (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
 
AclResult pg_attribute_aclcheck_all_ext (Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
 
AclResult pg_class_aclcheck (Oid table_oid, Oid roleid, AclMode mode)
 
AclResult pg_class_aclcheck_ext (Oid table_oid, Oid roleid, AclMode mode, bool *is_missing)
 
AclResult pg_parameter_aclcheck (const char *name, Oid roleid, AclMode mode)
 
AclResult pg_largeobject_aclcheck_snapshot (Oid lobj_oid, Oid roleid, AclMode mode, Snapshot snapshot)
 
bool object_ownercheck (Oid classid, Oid objectid, Oid roleid)
 
bool has_createrole_privilege (Oid roleid)
 
bool has_bypassrls_privilege (Oid roleid)
 
static Aclget_default_acl_internal (Oid roleId, Oid nsp_oid, char objtype)
 
Aclget_user_default_acl (ObjectType objtype, Oid ownerId, Oid nsp_oid)
 
void recordDependencyOnNewAcl (Oid classId, Oid objectId, int32 objsubId, Oid ownerId, Acl *acl)
 
void recordExtObjInitPriv (Oid objoid, Oid classoid)
 
void removeExtObjInitPriv (Oid objoid, Oid classoid)
 
void ReplaceRoleInInitPriv (Oid oldroleid, Oid newroleid, Oid classid, Oid objid, int32 objsubid)
 
void RemoveRoleFromInitPriv (Oid roleid, Oid classid, Oid objid, int32 objsubid)
 

Variables

bool binary_upgrade_record_init_privs = false
 

Function Documentation

◆ aclcheck_error()

void aclcheck_error ( AclResult  aclerr,
ObjectType  objtype,
const char objectname 
)

Definition at line 2672 of file aclchk.c.

2674{
2675 switch (aclerr)
2676 {
2677 case ACLCHECK_OK:
2678 /* no error, so return to caller */
2679 break;
2680 case ACLCHECK_NO_PRIV:
2681 {
2682 const char *msg = "???";
2683
2684 switch (objtype)
2685 {
2686 case OBJECT_AGGREGATE:
2687 msg = gettext_noop("permission denied for aggregate %s");
2688 break;
2689 case OBJECT_COLLATION:
2690 msg = gettext_noop("permission denied for collation %s");
2691 break;
2692 case OBJECT_COLUMN:
2693 msg = gettext_noop("permission denied for column %s");
2694 break;
2695 case OBJECT_CONVERSION:
2696 msg = gettext_noop("permission denied for conversion %s");
2697 break;
2698 case OBJECT_DATABASE:
2699 msg = gettext_noop("permission denied for database %s");
2700 break;
2701 case OBJECT_DOMAIN:
2702 msg = gettext_noop("permission denied for domain %s");
2703 break;
2705 msg = gettext_noop("permission denied for event trigger %s");
2706 break;
2707 case OBJECT_EXTENSION:
2708 msg = gettext_noop("permission denied for extension %s");
2709 break;
2710 case OBJECT_FDW:
2711 msg = gettext_noop("permission denied for foreign-data wrapper %s");
2712 break;
2714 msg = gettext_noop("permission denied for foreign server %s");
2715 break;
2717 msg = gettext_noop("permission denied for foreign table %s");
2718 break;
2719 case OBJECT_FUNCTION:
2720 msg = gettext_noop("permission denied for function %s");
2721 break;
2722 case OBJECT_INDEX:
2723 msg = gettext_noop("permission denied for index %s");
2724 break;
2725 case OBJECT_LANGUAGE:
2726 msg = gettext_noop("permission denied for language %s");
2727 break;
2728 case OBJECT_LARGEOBJECT:
2729 msg = gettext_noop("permission denied for large object %s");
2730 break;
2731 case OBJECT_MATVIEW:
2732 msg = gettext_noop("permission denied for materialized view %s");
2733 break;
2734 case OBJECT_OPCLASS:
2735 msg = gettext_noop("permission denied for operator class %s");
2736 break;
2737 case OBJECT_OPERATOR:
2738 msg = gettext_noop("permission denied for operator %s");
2739 break;
2740 case OBJECT_OPFAMILY:
2741 msg = gettext_noop("permission denied for operator family %s");
2742 break;
2744 msg = gettext_noop("permission denied for parameter %s");
2745 break;
2746 case OBJECT_POLICY:
2747 msg = gettext_noop("permission denied for policy %s");
2748 break;
2749 case OBJECT_PROCEDURE:
2750 msg = gettext_noop("permission denied for procedure %s");
2751 break;
2752 case OBJECT_PROPGRAPH:
2753 msg = gettext_noop("permission denied for property graph %s");
2754 break;
2755 case OBJECT_PUBLICATION:
2756 msg = gettext_noop("permission denied for publication %s");
2757 break;
2758 case OBJECT_ROUTINE:
2759 msg = gettext_noop("permission denied for routine %s");
2760 break;
2761 case OBJECT_SCHEMA:
2762 msg = gettext_noop("permission denied for schema %s");
2763 break;
2764 case OBJECT_SEQUENCE:
2765 msg = gettext_noop("permission denied for sequence %s");
2766 break;
2768 msg = gettext_noop("permission denied for statistics object %s");
2769 break;
2771 msg = gettext_noop("permission denied for subscription %s");
2772 break;
2773 case OBJECT_TABLE:
2774 msg = gettext_noop("permission denied for table %s");
2775 break;
2776 case OBJECT_TABLESPACE:
2777 msg = gettext_noop("permission denied for tablespace %s");
2778 break;
2780 msg = gettext_noop("permission denied for text search configuration %s");
2781 break;
2783 msg = gettext_noop("permission denied for text search dictionary %s");
2784 break;
2785 case OBJECT_TYPE:
2786 msg = gettext_noop("permission denied for type %s");
2787 break;
2788 case OBJECT_VIEW:
2789 msg = gettext_noop("permission denied for view %s");
2790 break;
2791 /* these currently aren't used */
2793 case OBJECT_AMOP:
2794 case OBJECT_AMPROC:
2795 case OBJECT_ATTRIBUTE:
2796 case OBJECT_CAST:
2797 case OBJECT_DEFAULT:
2798 case OBJECT_DEFACL:
2802 case OBJECT_ROLE:
2803 case OBJECT_RULE:
2805 case OBJECT_TRANSFORM:
2806 case OBJECT_TRIGGER:
2807 case OBJECT_TSPARSER:
2808 case OBJECT_TSTEMPLATE:
2810 elog(ERROR, "unsupported object type: %d", objtype);
2811 }
2812
2813 ereport(ERROR,
2815 errmsg(msg, objectname)));
2816 break;
2817 }
2818 case ACLCHECK_NOT_OWNER:
2819 {
2820 const char *msg = "???";
2821
2822 switch (objtype)
2823 {
2824 case OBJECT_AGGREGATE:
2825 msg = gettext_noop("must be owner of aggregate %s");
2826 break;
2827 case OBJECT_COLLATION:
2828 msg = gettext_noop("must be owner of collation %s");
2829 break;
2830 case OBJECT_CONVERSION:
2831 msg = gettext_noop("must be owner of conversion %s");
2832 break;
2833 case OBJECT_DATABASE:
2834 msg = gettext_noop("must be owner of database %s");
2835 break;
2836 case OBJECT_DOMAIN:
2837 msg = gettext_noop("must be owner of domain %s");
2838 break;
2840 msg = gettext_noop("must be owner of event trigger %s");
2841 break;
2842 case OBJECT_EXTENSION:
2843 msg = gettext_noop("must be owner of extension %s");
2844 break;
2845 case OBJECT_FDW:
2846 msg = gettext_noop("must be owner of foreign-data wrapper %s");
2847 break;
2849 msg = gettext_noop("must be owner of foreign server %s");
2850 break;
2852 msg = gettext_noop("must be owner of foreign table %s");
2853 break;
2854 case OBJECT_FUNCTION:
2855 msg = gettext_noop("must be owner of function %s");
2856 break;
2857 case OBJECT_INDEX:
2858 msg = gettext_noop("must be owner of index %s");
2859 break;
2860 case OBJECT_LANGUAGE:
2861 msg = gettext_noop("must be owner of language %s");
2862 break;
2863 case OBJECT_LARGEOBJECT:
2864 msg = gettext_noop("must be owner of large object %s");
2865 break;
2866 case OBJECT_MATVIEW:
2867 msg = gettext_noop("must be owner of materialized view %s");
2868 break;
2869 case OBJECT_OPCLASS:
2870 msg = gettext_noop("must be owner of operator class %s");
2871 break;
2872 case OBJECT_OPERATOR:
2873 msg = gettext_noop("must be owner of operator %s");
2874 break;
2875 case OBJECT_OPFAMILY:
2876 msg = gettext_noop("must be owner of operator family %s");
2877 break;
2878 case OBJECT_PROCEDURE:
2879 msg = gettext_noop("must be owner of procedure %s");
2880 break;
2881 case OBJECT_PROPGRAPH:
2882 msg = gettext_noop("must be owner of property graph %s");
2883 break;
2884 case OBJECT_PUBLICATION:
2885 msg = gettext_noop("must be owner of publication %s");
2886 break;
2887 case OBJECT_ROUTINE:
2888 msg = gettext_noop("must be owner of routine %s");
2889 break;
2890 case OBJECT_SEQUENCE:
2891 msg = gettext_noop("must be owner of sequence %s");
2892 break;
2894 msg = gettext_noop("must be owner of subscription %s");
2895 break;
2896 case OBJECT_TABLE:
2897 msg = gettext_noop("must be owner of table %s");
2898 break;
2899 case OBJECT_TYPE:
2900 msg = gettext_noop("must be owner of type %s");
2901 break;
2902 case OBJECT_VIEW:
2903 msg = gettext_noop("must be owner of view %s");
2904 break;
2905 case OBJECT_SCHEMA:
2906 msg = gettext_noop("must be owner of schema %s");
2907 break;
2909 msg = gettext_noop("must be owner of statistics object %s");
2910 break;
2911 case OBJECT_TABLESPACE:
2912 msg = gettext_noop("must be owner of tablespace %s");
2913 break;
2915 msg = gettext_noop("must be owner of text search configuration %s");
2916 break;
2918 msg = gettext_noop("must be owner of text search dictionary %s");
2919 break;
2920
2921 /*
2922 * Special cases: For these, the error message talks
2923 * about "relation", because that's where the
2924 * ownership is attached. See also
2925 * check_object_ownership().
2926 */
2927 case OBJECT_COLUMN:
2928 case OBJECT_POLICY:
2929 case OBJECT_RULE:
2931 case OBJECT_TRIGGER:
2932 msg = gettext_noop("must be owner of relation %s");
2933 break;
2934 /* these currently aren't used */
2936 case OBJECT_AMOP:
2937 case OBJECT_AMPROC:
2938 case OBJECT_ATTRIBUTE:
2939 case OBJECT_CAST:
2940 case OBJECT_DEFAULT:
2941 case OBJECT_DEFACL:
2946 case OBJECT_ROLE:
2947 case OBJECT_TRANSFORM:
2948 case OBJECT_TSPARSER:
2949 case OBJECT_TSTEMPLATE:
2951 elog(ERROR, "unsupported object type: %d", objtype);
2952 }
2953
2954 ereport(ERROR,
2956 errmsg(msg, objectname)));
2957 break;
2958 }
2959 default:
2960 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2961 break;
2962 }
2963}
@ ACLCHECK_NO_PRIV
Definition acl.h:185
@ ACLCHECK_OK
Definition acl.h:184
@ ACLCHECK_NOT_OWNER
Definition acl.h:186
#define gettext_noop(x)
Definition c.h:1285
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
static char * errmsg
@ OBJECT_EVENT_TRIGGER
@ OBJECT_FDW
@ OBJECT_TSPARSER
@ OBJECT_COLLATION
@ OBJECT_USER_MAPPING
@ OBJECT_PROPGRAPH
@ OBJECT_ACCESS_METHOD
@ OBJECT_OPCLASS
@ OBJECT_DEFACL
@ OBJECT_AGGREGATE
@ OBJECT_MATVIEW
@ OBJECT_SCHEMA
@ OBJECT_POLICY
@ OBJECT_OPERATOR
@ OBJECT_FOREIGN_TABLE
@ OBJECT_TSCONFIGURATION
@ OBJECT_OPFAMILY
@ OBJECT_DOMAIN
@ OBJECT_COLUMN
@ OBJECT_TABLESPACE
@ OBJECT_ROLE
@ OBJECT_ROUTINE
@ OBJECT_LARGEOBJECT
@ OBJECT_PUBLICATION_NAMESPACE
@ OBJECT_PROCEDURE
@ OBJECT_EXTENSION
@ OBJECT_INDEX
@ OBJECT_DEFAULT
@ OBJECT_DATABASE
@ OBJECT_SEQUENCE
@ OBJECT_TSTEMPLATE
@ OBJECT_LANGUAGE
@ OBJECT_AMOP
@ OBJECT_PUBLICATION_REL
@ OBJECT_FOREIGN_SERVER
@ OBJECT_TSDICTIONARY
@ OBJECT_ATTRIBUTE
@ OBJECT_PUBLICATION
@ OBJECT_RULE
@ OBJECT_CONVERSION
@ OBJECT_AMPROC
@ OBJECT_TABLE
@ OBJECT_VIEW
@ OBJECT_PARAMETER_ACL
@ OBJECT_TYPE
@ OBJECT_FUNCTION
@ OBJECT_TABCONSTRAINT
@ OBJECT_DOMCONSTRAINT
@ OBJECT_SUBSCRIPTION
@ OBJECT_STATISTIC_EXT
@ OBJECT_CAST
@ OBJECT_TRIGGER
@ OBJECT_TRANSFORM
static int fb(int x)

References ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog, ereport, errcode(), errmsg, ERROR, fb(), gettext_noop, OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_AMOP, OBJECT_AMPROC, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DEFACL, OBJECT_DEFAULT, OBJECT_DOMAIN, OBJECT_DOMCONSTRAINT, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRANSFORM, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, and OBJECT_VIEW.

Referenced by aclcheck_error_col(), aclcheck_error_type(), AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepSetTableSpace(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_object_ownership(), check_temp_tablespaces(), checkFkeyPermissions(), CheckFunctionValidatorAccess(), compute_return_type(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), currtid_internal(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecCheckPermissions(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), ExecuteTruncateGuts(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), gin_clean_pending_list(), HandleFunctionRequest(), heap_force_common(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), LockViewRecurse_walker(), LogicalRepSyncTableStart(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), MergeAttributes(), movedb(), OperatorCreate(), pg_get_database_ddl_internal(), pg_get_tablespace_ddl_internal(), pg_prewarm(), pgrowlocks(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDblink(), RangeVarCallbackForDropRelation(), RangeVarCallbackForLockTable(), RangeVarCallbackForPolicy(), RangeVarCallbackForReindexIndex(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackForStats(), RangeVarCallbackMaintainsTable(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), ReindexMultipleTables(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), restrict_and_check_grant(), ri_CheckPermissions(), subquery_planner(), TargetPrivilegesCheck(), transformTableLikeClause(), truncate_check_perms(), TypeCreate(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), ValidateOperatorReference(), and ValidateRestrictionEstimator().

◆ aclcheck_error_col()

void aclcheck_error_col ( AclResult  aclerr,
ObjectType  objtype,
const char objectname,
const char colname 
)

Definition at line 2967 of file aclchk.c.

2969{
2970 switch (aclerr)
2971 {
2972 case ACLCHECK_OK:
2973 /* no error, so return to caller */
2974 break;
2975 case ACLCHECK_NO_PRIV:
2976 ereport(ERROR,
2978 errmsg("permission denied for column \"%s\" of relation \"%s\"",
2979 colname, objectname)));
2980 break;
2981 case ACLCHECK_NOT_OWNER:
2982 /* relation msg is OK since columns don't have separate owners */
2983 aclcheck_error(aclerr, objtype, objectname);
2984 break;
2985 default:
2986 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2987 break;
2988 }
2989}
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2672

References aclcheck_error(), ACLCHECK_NO_PRIV, ACLCHECK_NOT_OWNER, ACLCHECK_OK, elog, ereport, errcode(), errmsg, ERROR, and fb().

Referenced by restrict_and_check_grant().

◆ aclcheck_error_type()

◆ ExecAlterDefaultPrivilegesStmt()

void ExecAlterDefaultPrivilegesStmt ( ParseState pstate,
AlterDefaultPrivilegesStmt stmt 
)

Definition at line 915 of file aclchk.c.

916{
917 GrantStmt *action = stmt->action;
919 ListCell *cell;
920 List *rolespecs = NIL;
921 List *nspnames = NIL;
925 const char *errormsg;
926
927 /* Deconstruct the "options" part of the statement */
928 foreach(cell, stmt->options)
929 {
930 DefElem *defel = (DefElem *) lfirst(cell);
931
932 if (strcmp(defel->defname, "schemas") == 0)
933 {
934 if (dnspnames)
937 }
938 else if (strcmp(defel->defname, "roles") == 0)
939 {
940 if (drolespecs)
943 }
944 else
945 elog(ERROR, "option \"%s\" not recognized", defel->defname);
946 }
947
948 if (dnspnames)
949 nspnames = (List *) dnspnames->arg;
950 if (drolespecs)
951 rolespecs = (List *) drolespecs->arg;
952
953 /* Prepare the InternalDefaultACL representation of the statement */
954 /* roleid to be filled below */
955 /* nspid to be filled in SetDefaultACLsInSchemas */
956 iacls.is_grant = action->is_grant;
957 iacls.objtype = action->objtype;
958 /* all_privs to be filled below */
959 /* privileges to be filled below */
960 iacls.grantees = NIL; /* filled below */
961 iacls.grant_option = action->grant_option;
962 iacls.grantor = action->grantor;
963 iacls.behavior = action->behavior;
964
965 /*
966 * Convert the RoleSpec list into an Oid list. Note that at this point we
967 * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
968 * there shouldn't be any additional work needed to support this case.
969 */
970 foreach(cell, action->grantees)
971 {
972 RoleSpec *grantee = (RoleSpec *) lfirst(cell);
974
975 switch (grantee->roletype)
976 {
977 case ROLESPEC_PUBLIC:
979 break;
980 default:
982 break;
983 }
984 iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
985 }
986
987 /*
988 * Convert action->privileges, a list of privilege strings, into an
989 * AclMode bitmask.
990 */
991 switch (action->objtype)
992 {
993 case OBJECT_TABLE:
995 errormsg = gettext_noop("invalid privilege type %s for relation");
996 break;
997 case OBJECT_SEQUENCE:
999 errormsg = gettext_noop("invalid privilege type %s for sequence");
1000 break;
1001 case OBJECT_FUNCTION:
1003 errormsg = gettext_noop("invalid privilege type %s for function");
1004 break;
1005 case OBJECT_PROCEDURE:
1007 errormsg = gettext_noop("invalid privilege type %s for procedure");
1008 break;
1009 case OBJECT_ROUTINE:
1011 errormsg = gettext_noop("invalid privilege type %s for routine");
1012 break;
1013 case OBJECT_TYPE:
1015 errormsg = gettext_noop("invalid privilege type %s for type");
1016 break;
1017 case OBJECT_SCHEMA:
1019 errormsg = gettext_noop("invalid privilege type %s for schema");
1020 break;
1021 case OBJECT_LARGEOBJECT:
1023 errormsg = gettext_noop("invalid privilege type %s for large object");
1024 break;
1025 case OBJECT_PROPGRAPH:
1027 errormsg = gettext_noop("invalid privilege type %s for property graph");
1028 break;
1029 default:
1030 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1031 (int) action->objtype);
1032 /* keep compiler quiet */
1034 errormsg = NULL;
1035 }
1036
1037 if (action->privileges == NIL)
1038 {
1039 iacls.all_privs = true;
1040
1041 /*
1042 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1043 * depending on the object type
1044 */
1045 iacls.privileges = ACL_NO_RIGHTS;
1046 }
1047 else
1048 {
1049 iacls.all_privs = false;
1050 iacls.privileges = ACL_NO_RIGHTS;
1051
1052 foreach(cell, action->privileges)
1053 {
1054 AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1055 AclMode priv;
1056
1057 if (privnode->cols)
1058 ereport(ERROR,
1060 errmsg("default privileges cannot be set for columns")));
1061
1062 if (privnode->priv_name == NULL) /* parser mistake? */
1063 elog(ERROR, "AccessPriv node must specify privilege");
1064 priv = string_to_privilege(privnode->priv_name);
1065
1066 if (priv & ~all_privileges)
1067 ereport(ERROR,
1069 errmsg(errormsg, privilege_to_string(priv))));
1070
1071 iacls.privileges |= priv;
1072 }
1073 }
1074
1075 if (rolespecs == NIL)
1076 {
1077 /* Set permissions for myself */
1078 iacls.roleid = GetUserId();
1079
1081 }
1082 else
1083 {
1084 /* Look up the role OIDs and do permissions checks */
1086
1087 foreach(rolecell, rolespecs)
1088 {
1090
1091 iacls.roleid = get_rolespec_oid(rolespec, false);
1092
1093 if (!has_privs_of_role(GetUserId(), iacls.roleid))
1094 ereport(ERROR,
1096 errmsg("permission denied to change default privileges")));
1097
1099 }
1100 }
1101}
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5639
#define ACL_ALL_RIGHTS_SCHEMA
Definition acl.h:170
#define ACL_ALL_RIGHTS_SEQUENCE
Definition acl.h:161
#define ACL_ALL_RIGHTS_PROPGRAPH
Definition acl.h:169
#define ACL_ALL_RIGHTS_FUNCTION
Definition acl.h:165
#define ACL_ALL_RIGHTS_TYPE
Definition acl.h:172
#define ACL_ALL_RIGHTS_RELATION
Definition acl.h:160
#define ACL_ID_PUBLIC
Definition acl.h:46
#define ACL_ALL_RIGHTS_LARGEOBJECT
Definition acl.h:167
static AclMode string_to_privilege(const char *privname)
Definition aclchk.c:2584
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition aclchk.c:1109
static const char * privilege_to_string(AclMode privilege)
Definition aclchk.c:2625
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition define.c:370
#define stmt
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
Oid GetUserId(void)
Definition miscinit.c:470
@ ROLESPEC_PUBLIC
Definition parsenodes.h:426
uint64 AclMode
Definition parsenodes.h:74
#define ACL_NO_RIGHTS
Definition parsenodes.h:92
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
Definition pg_list.h:54

References ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PROPGRAPH, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, elog, ereport, errcode(), errmsg, ERROR, errorConflictingDefElem(), fb(), get_rolespec_oid(), gettext_noop, GetUserId(), has_privs_of_role(), lappend_oid(), lfirst, NIL, OBJECT_FUNCTION, OBJECT_LARGEOBJECT, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, privilege_to_string(), ROLESPEC_PUBLIC, SetDefaultACLsInSchemas(), stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow().

◆ ExecGrant_Attribute()

static void ExecGrant_Attribute ( InternalGrant istmt,
Oid  relOid,
const char relname,
AttrNumber  attnum,
Oid  ownerId,
AclMode  col_privileges,
Relation  attRelation,
const Acl old_rel_acl 
)
static

Definition at line 1645 of file aclchk.c.

1648{
1651 Acl *old_acl;
1652 Acl *new_acl;
1653 Acl *merged_acl;
1655 bool isNull;
1656 Oid grantorId;
1658 bool need_update;
1659 HeapTuple newtuple;
1661 bool nulls[Natts_pg_attribute] = {0};
1662 bool replaces[Natts_pg_attribute] = {0};
1663 int noldmembers;
1664 int nnewmembers;
1665 Oid *oldmembers;
1666 Oid *newmembers;
1667
1669 ObjectIdGetDatum(relOid),
1672 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1673 attnum, relOid);
1675
1676 /*
1677 * Get working copy of existing ACL. If there's no ACL, substitute the
1678 * proper default.
1679 */
1681 &isNull);
1682 if (isNull)
1683 {
1684 old_acl = acldefault(OBJECT_COLUMN, ownerId);
1685 /* There are no old member roles according to the catalogs */
1686 noldmembers = 0;
1687 oldmembers = NULL;
1688 }
1689 else
1690 {
1692 /* Get the roles mentioned in the existing ACL */
1694 }
1695
1696 /*
1697 * In select_best_grantor we should consider existing table-level ACL bits
1698 * as well as the per-column ACL. Build a new ACL that is their
1699 * concatenation. (This is a bit cheap and dirty compared to merging them
1700 * properly with no duplications, but it's all we need here.)
1701 */
1703
1704 /* Determine ID to do the grant as, and available grant options */
1706 merged_acl, ownerId,
1708
1710
1711 /*
1712 * Restrict the privileges to what we can actually grant, and emit the
1713 * standards-mandated warning and error messages. Note: we don't track
1714 * whether the user actually used the ALL PRIVILEGES(columns) syntax for
1715 * each column; we just approximate it by whether all the possible
1716 * privileges are specified now. Since the all_privs flag only determines
1717 * whether a warning is issued, this seems close enough.
1718 */
1723 relOid, grantorId, OBJECT_COLUMN,
1724 relname, attnum,
1725 NameStr(pg_attribute_tuple->attname));
1726
1727 /*
1728 * Generate new ACL.
1729 */
1731 istmt->grant_option,
1732 istmt->behavior, istmt->grantees,
1734 ownerId);
1735
1736 /*
1737 * We need the members of both old and new ACLs so we can correct the
1738 * shared dependency information.
1739 */
1741
1742 /* finished building new ACL value, now insert it */
1743
1744 /*
1745 * If the updated ACL is empty, we can set attacl to null, and maybe even
1746 * avoid an update of the pg_attribute row. This is worth testing because
1747 * we'll come through here multiple times for any relation-level REVOKE,
1748 * even if there were never any column GRANTs. Note we are assuming that
1749 * the "default" ACL state for columns is empty.
1750 */
1751 if (ACL_NUM(new_acl) > 0)
1752 {
1754 need_update = true;
1755 }
1756 else
1757 {
1758 nulls[Anum_pg_attribute_attacl - 1] = true;
1759 need_update = !isNull;
1760 }
1762
1763 if (need_update)
1764 {
1766 values, nulls, replaces);
1767
1768 CatalogTupleUpdate(attRelation, &newtuple->t_self, newtuple);
1769
1770 /* Update initial privileges for extensions */
1772 ACL_NUM(new_acl) > 0 ? new_acl : NULL);
1773
1774 /* Update the shared dependency ACL info */
1776 ownerId,
1779 }
1780
1781 pfree(new_acl);
1782
1784}
Acl * aclconcat(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:491
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition acl.c:827
int aclmembers(const Acl *acl, Oid **roleids)
Definition acl.c:1568
void select_best_grantor(const RoleSpec *grantedBy, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
Definition acl.c:5508
#define ACL_ALL_RIGHTS_COLUMN
Definition acl.h:159
#define ACL_NUM(ACL)
Definition acl.h:108
#define DatumGetAclPCopy(X)
Definition acl.h:121
static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition aclchk.c:4645
static Acl * merge_acl_with_grant(Acl *old_acl, bool is_grant, bool grant_option, DropBehavior behavior, List *grantees, AclMode privileges, Oid grantorId, Oid ownerId)
Definition aclchk.c:182
static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions, bool all_privs, AclMode privileges, Oid objectId, Oid grantorId, ObjectType objtype, const char *objname, AttrNumber att_number, const char *colname)
Definition aclchk.c:241
static Datum values[MAXATTR]
Definition bootstrap.c:190
#define NameStr(name)
Definition c.h:835
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1118
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void pfree(void *pointer)
Definition mcxt.c:1619
int16 attnum
FormData_pg_attribute * Form_pg_attribute
NameData relname
Definition pg_class.h:40
void updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
static Datum Int16GetDatum(int16 X)
Definition postgres.h:172
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
#define PointerGetDatum(X)
Definition postgres.h:354
#define RelationGetDescr(relation)
Definition rel.h:542
ItemPointerData t_self
Definition htup.h:65
DropBehavior behavior
RoleSpec * grantor
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:231
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596

References ACL_ALL_RIGHTS_COLUMN, ACL_NUM, aclconcat(), acldefault(), aclmembers(), attnum, InternalGrant::behavior, CatalogTupleUpdate(), DatumGetAclPCopy, elog, ERROR, fb(), GETSTRUCT(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, heap_modify_tuple(), HeapTupleIsValid, Int16GetDatum(), InternalGrant::is_grant, merge_acl_with_grant(), NameStr, OBJECT_COLUMN, ObjectIdGetDatum(), pfree(), PointerGetDatum, recordExtensionInitPriv(), RelationGetDescr, ReleaseSysCache(), relname, restrict_and_check_grant(), SearchSysCache2(), select_best_grantor(), SysCacheGetAttr(), HeapTupleData::t_self, updateAclDependencies(), and values.

Referenced by ExecGrant_Relation().

◆ ExecGrant_common()

static void ExecGrant_common ( InternalGrant istmt,
Oid  classid,
AclMode  default_privs,
void(*)(InternalGrant *istmt, HeapTuple tuple)  object_check 
)
static

Definition at line 2133 of file aclchk.c.

2135{
2137 Relation relation;
2138 ListCell *cell;
2139
2140 if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
2141 istmt->privileges = default_privs;
2142
2144
2145 relation = table_open(classid, RowExclusiveLock);
2146
2147 foreach(cell, istmt->objects)
2148 {
2149 Oid objectid = lfirst_oid(cell);
2152 bool isNull;
2155 Acl *old_acl;
2156 Acl *new_acl;
2157 Oid grantorId;
2158 Oid ownerId;
2159 HeapTuple tuple;
2160 HeapTuple newtuple;
2161 Datum *values = palloc0_array(Datum, RelationGetDescr(relation)->natts);
2162 bool *nulls = palloc0_array(bool, RelationGetDescr(relation)->natts);
2163 bool *replaces = palloc0_array(bool, RelationGetDescr(relation)->natts);
2164 int noldmembers;
2165 int nnewmembers;
2166 Oid *oldmembers;
2167 Oid *newmembers;
2168
2170 if (!HeapTupleIsValid(tuple))
2171 elog(ERROR, "cache lookup failed for %s %u", get_object_class_descr(classid), objectid);
2172
2173 /*
2174 * Additional object-type-specific checks
2175 */
2176 if (object_check)
2177 object_check(istmt, tuple);
2178
2179 /*
2180 * Get owner ID and working copy of existing ACL. If there's no ACL,
2181 * substitute the proper default.
2182 */
2184 tuple,
2185 get_object_attnum_owner(classid)));
2187 tuple,
2188 get_object_attnum_acl(classid),
2189 &isNull);
2190 if (isNull)
2191 {
2192 old_acl = acldefault(get_object_type(classid, objectid), ownerId);
2193 /* There are no old member roles according to the catalogs */
2194 noldmembers = 0;
2195 oldmembers = NULL;
2196 }
2197 else
2198 {
2200 /* Get the roles mentioned in the existing ACL */
2202 }
2203
2204 /* Determine ID to do the grant as, and available grant options */
2205 select_best_grantor(istmt->grantor, istmt->privileges,
2206 old_acl, ownerId,
2208
2210 get_object_attnum_name(classid));
2211
2212 /*
2213 * Restrict the privileges to what we can actually grant, and emit the
2214 * standards-mandated warning and error messages.
2215 */
2218 istmt->all_privs, istmt->privileges,
2221 0, NULL);
2222
2223 /*
2224 * Generate new ACL.
2225 */
2227 istmt->grant_option, istmt->behavior,
2228 istmt->grantees, this_privileges,
2229 grantorId, ownerId);
2230
2231 /*
2232 * We need the members of both old and new ACLs so we can correct the
2233 * shared dependency information.
2234 */
2236
2237 /* finished building new ACL value, now insert it */
2238 replaces[get_object_attnum_acl(classid) - 1] = true;
2240
2241 newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values,
2242 nulls, replaces);
2243
2244 CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
2245 UnlockTuple(relation, &tuple->t_self, InplaceUpdateTupleLock);
2246
2247 /* Update initial privileges for extensions */
2249
2250 /* Update the shared dependency ACL info */
2251 updateAclDependencies(classid,
2252 objectid, 0,
2253 ownerId,
2256
2257 ReleaseSysCache(tuple);
2258
2259 pfree(new_acl);
2260
2261 /* prevent error when processing duplicate objects */
2263 }
2264
2265 table_close(relation, RowExclusiveLock);
2266}
#define palloc0_array(type, count)
Definition fe_memutils.h:92
void UnlockTuple(Relation relation, const ItemPointerData *tid, LOCKMODE lockmode)
Definition lmgr.c:601
#define InplaceUpdateTupleLock
Definition lockdefs.h:48
#define RowExclusiveLock
Definition lockdefs.h:38
AttrNumber get_object_attnum_owner(Oid class_id)
AttrNumber get_object_attnum_name(Oid class_id)
const char * get_object_class_descr(Oid class_id)
AttrNumber get_object_attnum_acl(Oid class_id)
SysCacheIdentifier get_object_catcache_oid(Oid class_id)
ObjectType get_object_type(Oid class_id, Oid object_id)
#define lfirst_oid(lc)
Definition pg_list.h:174
static Name DatumGetName(Datum X)
Definition postgres.h:393
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
HeapTuple SearchSysCacheLocked1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:283
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:626
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
void CommandCounterIncrement(void)
Definition xact.c:1130

References ACL_NO_RIGHTS, acldefault(), aclmembers(), InternalGrant::all_privs, InternalGrant::behavior, CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, DatumGetName(), DatumGetObjectId(), elog, ERROR, fb(), get_object_attnum_acl(), get_object_attnum_name(), get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), get_object_type(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, heap_modify_tuple(), HeapTupleIsValid, InplaceUpdateTupleLock, InternalGrant::is_grant, lfirst_oid, merge_acl_with_grant(), NameStr, ObjectIdGetDatum(), InternalGrant::objects, palloc0_array, pfree(), PointerGetDatum, InternalGrant::privileges, recordExtensionInitPriv(), RelationGetDescr, ReleaseSysCache(), restrict_and_check_grant(), RowExclusiveLock, SearchSysCacheLocked1(), select_best_grantor(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), HeapTupleData::t_self, table_close(), table_open(), UnlockTuple(), updateAclDependencies(), and values.

Referenced by ExecGrantStmt_oids().

◆ ExecGrant_Language_check()

static void ExecGrant_Language_check ( InternalGrant istmt,
HeapTuple  tuple 
)
static

Definition at line 2269 of file aclchk.c.

2270{
2272
2274
2275 if (!pg_language_tuple->lanpltrusted)
2276 ereport(ERROR,
2278 errmsg("language \"%s\" is not trusted",
2279 NameStr(pg_language_tuple->lanname)),
2280 errdetail("GRANT and REVOKE are not allowed on untrusted languages, "
2281 "because only superusers can use untrusted languages.")));
2282}
int errdetail(const char *fmt,...) pg_attribute_printf(1
END_CATALOG_STRUCT typedef FormData_pg_language * Form_pg_language
Definition pg_language.h:69

References ereport, errcode(), errdetail(), errmsg, ERROR, fb(), Form_pg_language, GETSTRUCT(), and NameStr.

Referenced by ExecGrantStmt_oids().

◆ ExecGrant_Largeobject()

static void ExecGrant_Largeobject ( InternalGrant istmt)
static

Definition at line 2285 of file aclchk.c.

2286{
2287 Relation relation;
2288 ListCell *cell;
2289
2290 if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
2292
2295
2296 foreach(cell, istmt->objects)
2297 {
2298 Oid loid = lfirst_oid(cell);
2300 char loname[NAMEDATALEN];
2302 bool isNull;
2305 Acl *old_acl;
2306 Acl *new_acl;
2307 Oid grantorId;
2308 Oid ownerId;
2309 HeapTuple newtuple;
2311 bool nulls[Natts_pg_largeobject_metadata] = {0};
2313 int noldmembers;
2314 int nnewmembers;
2315 Oid *oldmembers;
2316 Oid *newmembers;
2317 ScanKeyData entry[1];
2318 SysScanDesc scan;
2319 HeapTuple tuple;
2320
2321 /* There's no syscache for pg_largeobject_metadata */
2322 ScanKeyInit(&entry[0],
2326
2327 scan = systable_beginscan(relation,
2329 NULL, 1, entry);
2330
2331 tuple = systable_getnext(scan);
2332 if (!HeapTupleIsValid(tuple))
2333 elog(ERROR, "could not find tuple for large object %u", loid);
2334
2336
2337 /*
2338 * Get owner ID and working copy of existing ACL. If there's no ACL,
2339 * substitute the proper default.
2340 */
2341 ownerId = form_lo_meta->lomowner;
2342 aclDatum = heap_getattr(tuple,
2344 RelationGetDescr(relation), &isNull);
2345 if (isNull)
2346 {
2348 /* There are no old member roles according to the catalogs */
2349 noldmembers = 0;
2350 oldmembers = NULL;
2351 }
2352 else
2353 {
2355 /* Get the roles mentioned in the existing ACL */
2357 }
2358
2359 /* Determine ID to do the grant as, and available grant options */
2360 select_best_grantor(istmt->grantor, istmt->privileges,
2361 old_acl, ownerId,
2363
2364 /*
2365 * Restrict the privileges to what we can actually grant, and emit the
2366 * standards-mandated warning and error messages.
2367 */
2368 snprintf(loname, sizeof(loname), "large object %u", loid);
2371 istmt->all_privs, istmt->privileges,
2373 loname, 0, NULL);
2374
2375 /*
2376 * Generate new ACL.
2377 */
2379 istmt->grant_option, istmt->behavior,
2380 istmt->grantees, this_privileges,
2381 grantorId, ownerId);
2382
2383 /*
2384 * We need the members of both old and new ACLs so we can correct the
2385 * shared dependency information.
2386 */
2388
2389 /* finished building new ACL value, now insert it */
2393
2394 newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation),
2395 values, nulls, replaces);
2396
2397 CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
2398
2399 /* Update initial privileges for extensions */
2401
2402 /* Update the shared dependency ACL info */
2404 form_lo_meta->oid, 0,
2405 ownerId,
2408
2409 systable_endscan(scan);
2410
2411 pfree(new_acl);
2412
2413 /* prevent error when processing duplicate objects */
2415 }
2416
2417 table_close(relation, RowExclusiveLock);
2418}
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:612
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:523
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define NAMEDATALEN
END_CATALOG_STRUCT typedef FormData_pg_largeobject_metadata * Form_pg_largeobject_metadata
#define snprintf
Definition port.h:261
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31

References ACL_ALL_RIGHTS_LARGEOBJECT, ACL_NO_RIGHTS, acldefault(), aclmembers(), InternalGrant::all_privs, InternalGrant::behavior, BTEqualStrategyNumber, CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, elog, ERROR, fb(), Form_pg_largeobject_metadata, GETSTRUCT(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, InternalGrant::is_grant, lfirst_oid, merge_acl_with_grant(), NAMEDATALEN, OBJECT_LARGEOBJECT, ObjectIdGetDatum(), InternalGrant::objects, pfree(), PointerGetDatum, InternalGrant::privileges, recordExtensionInitPriv(), RelationGetDescr, restrict_and_check_grant(), RowExclusiveLock, ScanKeyInit(), select_best_grantor(), snprintf, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), updateAclDependencies(), and values.

Referenced by ExecGrantStmt_oids().

◆ ExecGrant_Parameter()

static void ExecGrant_Parameter ( InternalGrant istmt)
static

Definition at line 2441 of file aclchk.c.

2442{
2443 Relation relation;
2444 ListCell *cell;
2445
2446 if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
2448
2450
2451 foreach(cell, istmt->objects)
2452 {
2453 Oid parameterId = lfirst_oid(cell);
2455 const char *parname;
2457 bool isNull;
2460 Acl *old_acl;
2461 Acl *new_acl;
2462 Oid grantorId;
2463 Oid ownerId;
2464 HeapTuple tuple;
2465 int noldmembers;
2466 int nnewmembers;
2467 Oid *oldmembers;
2468 Oid *newmembers;
2469
2471 if (!HeapTupleIsValid(tuple))
2472 elog(ERROR, "cache lookup failed for parameter ACL %u",
2473 parameterId);
2474
2475 /* We'll need the GUC's name */
2479
2480 /* Treat all parameters as belonging to the bootstrap superuser. */
2481 ownerId = BOOTSTRAP_SUPERUSERID;
2482
2483 /*
2484 * Get working copy of existing ACL. If there's no ACL, substitute the
2485 * proper default.
2486 */
2489 &isNull);
2490
2491 if (isNull)
2492 {
2493 old_acl = acldefault(istmt->objtype, ownerId);
2494 /* There are no old member roles according to the catalogs */
2495 noldmembers = 0;
2496 oldmembers = NULL;
2497 }
2498 else
2499 {
2501 /* Get the roles mentioned in the existing ACL */
2503 }
2504
2505 /* Determine ID to do the grant as, and available grant options */
2506 select_best_grantor(istmt->grantor, istmt->privileges,
2507 old_acl, ownerId,
2509
2510 /*
2511 * Restrict the privileges to what we can actually grant, and emit the
2512 * standards-mandated warning and error messages.
2513 */
2516 istmt->all_privs, istmt->privileges,
2519 parname,
2520 0, NULL);
2521
2522 /*
2523 * Generate new ACL.
2524 */
2526 istmt->grant_option, istmt->behavior,
2527 istmt->grantees, this_privileges,
2528 grantorId, ownerId);
2529
2530 /*
2531 * We need the members of both old and new ACLs so we can correct the
2532 * shared dependency information.
2533 */
2535
2536 /*
2537 * If the new ACL is equal to the default, we don't need the catalog
2538 * entry any longer. Delete it rather than updating it, to avoid
2539 * leaving a degenerate entry.
2540 */
2541 if (aclequal(new_acl, acldefault(istmt->objtype, ownerId)))
2542 {
2543 CatalogTupleDelete(relation, &tuple->t_self);
2544 }
2545 else
2546 {
2547 /* finished building new ACL value, now insert it */
2548 HeapTuple newtuple;
2550 bool nulls[Natts_pg_parameter_acl] = {0};
2551 bool replaces[Natts_pg_parameter_acl] = {0};
2552
2555
2556 newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation),
2557 values, nulls, replaces);
2558
2559 CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
2560 }
2561
2562 /* Update initial privileges for extensions */
2564 new_acl);
2565
2566 /* Update the shared dependency ACL info */
2568 ownerId,
2571
2572 ReleaseSysCache(tuple);
2573 pfree(new_acl);
2574
2575 /* prevent error when processing duplicate objects */
2577 }
2578
2579 table_close(relation, RowExclusiveLock);
2580}
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:573
#define ACL_ALL_RIGHTS_PARAMETER_ACL
Definition acl.h:168
#define TextDatumGetCString(d)
Definition builtins.h:99
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
ObjectType objtype
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221

References ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_NO_RIGHTS, acldefault(), aclequal(), aclmembers(), InternalGrant::all_privs, InternalGrant::behavior, CatalogTupleDelete(), CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, elog, ERROR, fb(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, heap_modify_tuple(), HeapTupleIsValid, InternalGrant::is_grant, lfirst_oid, merge_acl_with_grant(), OBJECT_PARAMETER_ACL, ObjectIdGetDatum(), InternalGrant::objects, InternalGrant::objtype, pfree(), PointerGetDatum, InternalGrant::privileges, recordExtensionInitPriv(), RelationGetDescr, ReleaseSysCache(), restrict_and_check_grant(), RowExclusiveLock, SearchSysCache1(), select_best_grantor(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), HeapTupleData::t_self, table_close(), table_open(), TextDatumGetCString, updateAclDependencies(), and values.

Referenced by ExecGrantStmt_oids().

◆ ExecGrant_Relation()

static void ExecGrant_Relation ( InternalGrant istmt)
static

Definition at line 1790 of file aclchk.c.

1791{
1792 Relation relation;
1794 ListCell *cell;
1795
1798
1799 foreach(cell, istmt->objects)
1800 {
1801 Oid relOid = lfirst_oid(cell);
1804 bool isNull;
1809 Acl *old_acl;
1811 int noldmembers;
1812 Oid *oldmembers;
1813 Oid ownerId;
1814 HeapTuple tuple;
1816
1818 if (!HeapTupleIsValid(tuple))
1819 elog(ERROR, "cache lookup failed for relation %u", relOid);
1821
1822 /* Not sensible to grant on an index */
1823 if (pg_class_tuple->relkind == RELKIND_INDEX ||
1825 ereport(ERROR,
1827 errmsg("\"%s\" is an index",
1828 NameStr(pg_class_tuple->relname))));
1829
1830 /* Composite types aren't tables either */
1831 if (pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
1832 ereport(ERROR,
1834 errmsg("\"%s\" is a composite type",
1835 NameStr(pg_class_tuple->relname))));
1836
1837 /* Used GRANT SEQUENCE on a non-sequence? */
1838 if (istmt->objtype == OBJECT_SEQUENCE &&
1839 pg_class_tuple->relkind != RELKIND_SEQUENCE)
1840 ereport(ERROR,
1842 errmsg("\"%s\" is not a sequence",
1843 NameStr(pg_class_tuple->relname))));
1844
1845 if (istmt->objtype == OBJECT_PROPGRAPH &&
1847 ereport(ERROR,
1849 errmsg("\"%s\" is not a property graph",
1850 NameStr(pg_class_tuple->relname))));
1851
1852 /* Adjust the default permissions based on object type */
1853 if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
1854 {
1855 if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
1857 else if (pg_class_tuple->relkind == RELKIND_PROPGRAPH)
1859 else
1861 }
1862 else
1863 this_privileges = istmt->privileges;
1864
1865 /*
1866 * The GRANT TABLE syntax can be used for sequences and non-sequences,
1867 * so we have to look at the relkind to determine the supported
1868 * permissions. The OR of table and sequence permissions were already
1869 * checked.
1870 */
1871 if (istmt->objtype == OBJECT_TABLE)
1872 {
1873 if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
1874 {
1875 /*
1876 * For backward compatibility, just throw a warning for
1877 * invalid sequence permissions when using the non-sequence
1878 * GRANT syntax.
1879 */
1881 {
1882 /*
1883 * Mention the object name because the user needs to know
1884 * which operations succeeded. This is required because
1885 * WARNING allows the command to continue.
1886 */
1889 errmsg("sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges",
1890 NameStr(pg_class_tuple->relname))));
1892 }
1893 }
1894 else
1895 {
1897 {
1898 /*
1899 * USAGE is the only permission supported by sequences but
1900 * not by non-sequences. Don't mention the object name
1901 * because we didn't in the combined TABLE | SEQUENCE
1902 * check.
1903 */
1904 ereport(ERROR,
1906 errmsg("invalid privilege type %s for table",
1907 "USAGE")));
1908 }
1909 }
1910 }
1911
1912 /*
1913 * Set up array in which we'll accumulate any column privilege bits
1914 * that need modification. The array is indexed such that entry [0]
1915 * corresponds to FirstLowInvalidHeapAttributeNumber.
1916 */
1919 have_col_privileges = false;
1920
1921 /*
1922 * If we are revoking relation privileges that are also column
1923 * privileges, we must implicitly revoke them from each column too,
1924 * per SQL spec. (We don't need to implicitly add column privileges
1925 * during GRANT because the permissions-checking code always checks
1926 * both relation and per-column privileges.)
1927 */
1928 if (!istmt->is_grant &&
1930 {
1935 have_col_privileges = true;
1936 }
1937
1938 /*
1939 * Get owner ID and working copy of existing ACL. If there's no ACL,
1940 * substitute the proper default.
1941 */
1942 ownerId = pg_class_tuple->relowner;
1944 &isNull);
1945 if (isNull)
1946 {
1947 switch (pg_class_tuple->relkind)
1948 {
1949 case RELKIND_SEQUENCE:
1951 break;
1952 case RELKIND_PROPGRAPH:
1954 break;
1955 default:
1956 old_acl = acldefault(OBJECT_TABLE, ownerId);
1957 break;
1958 }
1959 /* There are no old member roles according to the catalogs */
1960 noldmembers = 0;
1961 oldmembers = NULL;
1962 }
1963 else
1964 {
1966 /* Get the roles mentioned in the existing ACL */
1968 }
1969
1970 /* Need an extra copy of original rel ACL for column handling */
1972
1973 /*
1974 * Handle relation-level privileges, if any were specified
1975 */
1977 {
1979 Acl *new_acl;
1980 Oid grantorId;
1981 HeapTuple newtuple;
1983 bool nulls[Natts_pg_class] = {0};
1984 bool replaces[Natts_pg_class] = {0};
1985 int nnewmembers;
1986 Oid *newmembers;
1987 ObjectType objtype;
1988
1989 /* Determine ID to do the grant as, and available grant options */
1991 old_acl, ownerId,
1993
1994 switch (pg_class_tuple->relkind)
1995 {
1996 case RELKIND_SEQUENCE:
1997 objtype = OBJECT_SEQUENCE;
1998 break;
1999 default:
2000 objtype = OBJECT_TABLE;
2001 break;
2002 }
2003
2004 /*
2005 * Restrict the privileges to what we can actually grant, and emit
2006 * the standards-mandated warning and error messages.
2007 */
2010 istmt->all_privs, this_privileges,
2011 relOid, grantorId, objtype,
2012 NameStr(pg_class_tuple->relname),
2013 0, NULL);
2014
2015 /*
2016 * Generate new ACL.
2017 */
2019 istmt->is_grant,
2020 istmt->grant_option,
2021 istmt->behavior,
2022 istmt->grantees,
2024 grantorId,
2025 ownerId);
2026
2027 /*
2028 * We need the members of both old and new ACLs so we can correct
2029 * the shared dependency information.
2030 */
2032
2033 /* finished building new ACL value, now insert it */
2034 replaces[Anum_pg_class_relacl - 1] = true;
2036
2037 newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation),
2038 values, nulls, replaces);
2039
2040 CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
2041 UnlockTuple(relation, &tuple->t_self, InplaceUpdateTupleLock);
2042
2043 /* Update initial privileges for extensions */
2045
2046 /* Update the shared dependency ACL info */
2048 ownerId,
2051
2052 pfree(new_acl);
2053 }
2054 else
2055 UnlockTuple(relation, &tuple->t_self, InplaceUpdateTupleLock);
2056
2057 /*
2058 * Handle column-level privileges, if any were specified or implied.
2059 * We first expand the user-specified column privileges into the
2060 * array, and then iterate over all nonempty array entries.
2061 */
2062 foreach(cell_colprivs, istmt->col_privs)
2063 {
2064 AccessPriv *col_privs = (AccessPriv *) lfirst(cell_colprivs);
2065
2066 if (col_privs->priv_name == NULL)
2068 else
2070
2072 ereport(ERROR,
2074 errmsg("invalid privilege type %s for column",
2076
2077 if (pg_class_tuple->relkind == RELKIND_SEQUENCE &&
2079 {
2080 /*
2081 * The only column privilege allowed on sequences is SELECT.
2082 * This is a warning not error because we do it that way for
2083 * relation-level privileges.
2084 */
2087 errmsg("sequence \"%s\" only supports SELECT column privileges",
2088 NameStr(pg_class_tuple->relname))));
2089
2091 }
2092
2093 expand_col_privileges(col_privs->cols, relOid,
2097 have_col_privileges = true;
2098 }
2099
2101 {
2102 AttrNumber i;
2103
2104 for (i = 0; i < num_col_privileges; i++)
2105 {
2107 continue;
2108 ExecGrant_Attribute(istmt,
2109 relOid,
2110 NameStr(pg_class_tuple->relname),
2112 ownerId,
2115 old_rel_acl);
2116 }
2117 }
2118
2121
2122 ReleaseSysCache(tuple);
2123
2124 /* prevent error when processing duplicate objects */
2126 }
2127
2129 table_close(relation, RowExclusiveLock);
2130}
Acl * aclcopy(const Acl *orig_acl)
Definition acl.c:471
static void expand_all_col_privileges(Oid table_oid, Form_pg_class classForm, AclMode this_privileges, AclMode *col_privileges, int num_col_privileges)
Definition aclchk.c:1599
static void expand_col_privileges(List *colnames, Oid table_oid, AclMode this_privileges, AclMode *col_privileges, int num_col_privileges)
Definition aclchk.c:1566
static void ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname, AttrNumber attnum, Oid ownerId, AclMode col_privileges, Relation attRelation, const Acl *old_rel_acl)
Definition aclchk.c:1645
int16 AttrNumber
Definition attnum.h:21
#define WARNING
Definition elog.h:37
int i
Definition isn.c:77
void * palloc0(Size size)
Definition mcxt.c:1420
ObjectType
#define ACL_SELECT
Definition parsenodes.h:77
FormData_pg_class * Form_pg_class
Definition pg_class.h:160
char * priv_name
List * cols
#define FirstLowInvalidHeapAttributeNumber
Definition sysattr.h:27

References ACL_ALL_RIGHTS_COLUMN, ACL_ALL_RIGHTS_PROPGRAPH, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SEQUENCE, ACL_NO_RIGHTS, ACL_SELECT, aclcopy(), acldefault(), aclmembers(), InternalGrant::all_privs, InternalGrant::behavior, CatalogTupleUpdate(), InternalGrant::col_privs, AccessPriv::cols, CommandCounterIncrement(), DatumGetAclPCopy, elog, ereport, errcode(), errmsg, ERROR, ExecGrant_Attribute(), expand_all_col_privileges(), expand_col_privileges(), fb(), FirstLowInvalidHeapAttributeNumber, GETSTRUCT(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, heap_modify_tuple(), HeapTupleIsValid, i, InplaceUpdateTupleLock, InternalGrant::is_grant, lfirst, lfirst_oid, merge_acl_with_grant(), NameStr, OBJECT_PROPGRAPH, OBJECT_SEQUENCE, OBJECT_TABLE, ObjectIdGetDatum(), InternalGrant::objects, InternalGrant::objtype, palloc0(), pfree(), PointerGetDatum, AccessPriv::priv_name, privilege_to_string(), InternalGrant::privileges, recordExtensionInitPriv(), RelationGetDescr, ReleaseSysCache(), restrict_and_check_grant(), RowExclusiveLock, SearchSysCacheLocked1(), select_best_grantor(), string_to_privilege(), SysCacheGetAttr(), HeapTupleData::t_self, table_close(), table_open(), UnlockTuple(), updateAclDependencies(), values, and WARNING.

Referenced by ExecGrantStmt_oids().

◆ ExecGrant_Type_check()

static void ExecGrant_Type_check ( InternalGrant istmt,
HeapTuple  tuple 
)
static

Definition at line 2421 of file aclchk.c.

2422{
2424
2426
2427 /* Disallow GRANT on dependent types */
2429 ereport(ERROR,
2431 errmsg("cannot set privileges of array types"),
2432 errhint("Set the privileges of the element type instead.")));
2433 if (pg_type_tuple->typtype == TYPTYPE_MULTIRANGE)
2434 ereport(ERROR,
2436 errmsg("cannot set privileges of multirange types"),
2437 errhint("Set the privileges of the range type instead.")));
2438}
int errhint(const char *fmt,...) pg_attribute_printf(1
END_CATALOG_STRUCT typedef FormData_pg_type * Form_pg_type
Definition pg_type.h:265

References ereport, errcode(), errhint(), errmsg, ERROR, fb(), Form_pg_type, and GETSTRUCT().

Referenced by ExecGrantStmt_oids().

◆ ExecGrantStmt_oids()

static void ExecGrantStmt_oids ( InternalGrant istmt)
static

Definition at line 594 of file aclchk.c.

595{
596 switch (istmt->objtype)
597 {
598 case OBJECT_TABLE:
599 case OBJECT_SEQUENCE:
600 case OBJECT_PROPGRAPH:
601 ExecGrant_Relation(istmt);
602 break;
603 case OBJECT_DATABASE:
605 break;
606 case OBJECT_DOMAIN:
607 case OBJECT_TYPE:
609 break;
610 case OBJECT_FDW:
612 break;
615 break;
616 case OBJECT_FUNCTION:
617 case OBJECT_PROCEDURE:
618 case OBJECT_ROUTINE:
620 break;
621 case OBJECT_LANGUAGE:
623 break;
626 break;
627 case OBJECT_SCHEMA:
629 break;
632 break;
634 ExecGrant_Parameter(istmt);
635 break;
636 default:
637 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
638 (int) istmt->objtype);
639 }
640
641 /*
642 * Pass the info to event triggers about the just-executed GRANT. Note
643 * that we prefer to do it after actually executing it, because that gives
644 * the functions a chance to adjust the istmt with privileges actually
645 * granted.
646 */
649}
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
Definition acl.h:164
#define ACL_ALL_RIGHTS_TABLESPACE
Definition acl.h:171
#define ACL_ALL_RIGHTS_DATABASE
Definition acl.h:162
#define ACL_ALL_RIGHTS_LANGUAGE
Definition acl.h:166
#define ACL_ALL_RIGHTS_FDW
Definition acl.h:163
static void ExecGrant_Type_check(InternalGrant *istmt, HeapTuple tuple)
Definition aclchk.c:2421
static void ExecGrant_common(InternalGrant *istmt, Oid classid, AclMode default_privs, void(*object_check)(InternalGrant *istmt, HeapTuple tuple))
Definition aclchk.c:2133
static void ExecGrant_Largeobject(InternalGrant *istmt)
Definition aclchk.c:2285
static void ExecGrant_Parameter(InternalGrant *istmt)
Definition aclchk.c:2441
static void ExecGrant_Relation(InternalGrant *istmt)
Definition aclchk.c:1790
static void ExecGrant_Language_check(InternalGrant *istmt, HeapTuple tuple)
Definition aclchk.c:2269
bool EventTriggerSupportsObjectType(ObjectType obtype)
void EventTriggerCollectGrant(InternalGrant *istmt)

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, elog, ERROR, EventTriggerCollectGrant(), EventTriggerSupportsObjectType(), ExecGrant_common(), ExecGrant_Language_check(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), ExecGrant_Type_check(), fb(), OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, and InternalGrant::objtype.

Referenced by ExecuteGrantStmt(), and RemoveRoleFromObjectACL().

◆ ExecuteGrantStmt()

void ExecuteGrantStmt ( GrantStmt stmt)

Definition at line 395 of file aclchk.c.

396{
397 InternalGrant istmt;
398 ListCell *cell;
399 const char *errormsg;
401
402 /*
403 * Turn the regular GrantStmt into the InternalGrant form.
404 */
405 istmt.is_grant = stmt->is_grant;
406 istmt.objtype = stmt->objtype;
407
408 /* Collect the OIDs of the target objects */
409 switch (stmt->targtype)
410 {
412 istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects,
413 stmt->is_grant);
414 break;
416 istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
417 break;
418 /* ACL_TARGET_DEFAULTS should not be seen here */
419 default:
420 elog(ERROR, "unrecognized GrantStmt.targtype: %d",
421 (int) stmt->targtype);
422 }
423
424 /* all_privs to be filled below */
425 /* privileges to be filled below */
426 istmt.col_privs = NIL; /* may get filled below */
427 istmt.grantees = NIL; /* filled below */
428 istmt.grant_option = stmt->grant_option;
429 istmt.grantor = stmt->grantor;
430 istmt.behavior = stmt->behavior;
431
432 /*
433 * Convert the RoleSpec list into an Oid list. Note that at this point we
434 * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
435 * there shouldn't be any additional work needed to support this case.
436 */
437 foreach(cell, stmt->grantees)
438 {
439 RoleSpec *grantee = (RoleSpec *) lfirst(cell);
441
442 switch (grantee->roletype)
443 {
444 case ROLESPEC_PUBLIC:
446 break;
447 default:
449 break;
450 }
452 }
453
454 /*
455 * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode
456 * bitmask. Note: objtype can't be OBJECT_COLUMN.
457 */
458 switch (stmt->objtype)
459 {
460 case OBJECT_TABLE:
461
462 /*
463 * Because this might be a sequence, we test both relation and
464 * sequence bits, and later do a more limited test when we know
465 * the object type.
466 */
468 errormsg = gettext_noop("invalid privilege type %s for relation");
469 break;
470 case OBJECT_SEQUENCE:
472 errormsg = gettext_noop("invalid privilege type %s for sequence");
473 break;
474 case OBJECT_DATABASE:
476 errormsg = gettext_noop("invalid privilege type %s for database");
477 break;
478 case OBJECT_DOMAIN:
480 errormsg = gettext_noop("invalid privilege type %s for domain");
481 break;
482 case OBJECT_FUNCTION:
484 errormsg = gettext_noop("invalid privilege type %s for function");
485 break;
486 case OBJECT_LANGUAGE:
488 errormsg = gettext_noop("invalid privilege type %s for language");
489 break;
492 errormsg = gettext_noop("invalid privilege type %s for large object");
493 break;
494 case OBJECT_SCHEMA:
496 errormsg = gettext_noop("invalid privilege type %s for schema");
497 break;
498 case OBJECT_PROCEDURE:
500 errormsg = gettext_noop("invalid privilege type %s for procedure");
501 break;
502 case OBJECT_ROUTINE:
504 errormsg = gettext_noop("invalid privilege type %s for routine");
505 break;
508 errormsg = gettext_noop("invalid privilege type %s for tablespace");
509 break;
510 case OBJECT_TYPE:
512 errormsg = gettext_noop("invalid privilege type %s for type");
513 break;
514 case OBJECT_FDW:
516 errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper");
517 break;
520 errormsg = gettext_noop("invalid privilege type %s for foreign server");
521 break;
524 errormsg = gettext_noop("invalid privilege type %s for parameter");
525 break;
526 case OBJECT_PROPGRAPH:
528 errormsg = gettext_noop("invalid privilege type %s for property graph");
529 break;
530 default:
531 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
532 (int) stmt->objtype);
533 /* keep compiler quiet */
535 errormsg = NULL;
536 }
537
538 if (stmt->privileges == NIL)
539 {
540 istmt.all_privs = true;
541
542 /*
543 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
544 * depending on the object type
545 */
547 }
548 else
549 {
550 istmt.all_privs = false;
552
553 foreach(cell, stmt->privileges)
554 {
556 AclMode priv;
557
558 /*
559 * If it's a column-level specification, we just set it aside in
560 * col_privs for the moment; but insist it's for a relation.
561 */
562 if (privnode->cols)
563 {
564 if (stmt->objtype != OBJECT_TABLE)
567 errmsg("column privileges are only valid for relations")));
568 istmt.col_privs = lappend(istmt.col_privs, privnode);
569 continue;
570 }
571
572 if (privnode->priv_name == NULL) /* parser mistake? */
573 elog(ERROR, "AccessPriv node must specify privilege or columns");
574 priv = string_to_privilege(privnode->priv_name);
575
576 if (priv & ~all_privileges)
579 errmsg(errormsg, privilege_to_string(priv))));
580
581 istmt.privileges |= priv;
582 }
583 }
584
585 ExecGrantStmt_oids(&istmt);
586}
static void ExecGrantStmt_oids(InternalGrant *istmt)
Definition aclchk.c:594
static List * objectNamesToOids(ObjectType objtype, List *objnames, bool is_grant)
Definition aclchk.c:671
static List * objectsInSchemaToOids(ObjectType objtype, List *nspnames)
Definition aclchk.c:784
List * lappend(List *list, void *datum)
Definition list.c:339
@ ACL_TARGET_OBJECT
@ ACL_TARGET_ALL_IN_SCHEMA

References ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_PROPGRAPH, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_ID_PUBLIC, ACL_NO_RIGHTS, ACL_TARGET_ALL_IN_SCHEMA, ACL_TARGET_OBJECT, InternalGrant::all_privs, InternalGrant::behavior, InternalGrant::col_privs, elog, ereport, errcode(), errmsg, ERROR, ExecGrantStmt_oids(), fb(), get_rolespec_oid(), gettext_noop, InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, InternalGrant::is_grant, lappend(), lappend_oid(), lfirst, NIL, OBJECT_DATABASE, OBJECT_DOMAIN, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, objectNamesToOids(), InternalGrant::objects, objectsInSchemaToOids(), InternalGrant::objtype, privilege_to_string(), InternalGrant::privileges, ROLESPEC_PUBLIC, stmt, and string_to_privilege().

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ expand_all_col_privileges()

static void expand_all_col_privileges ( Oid  table_oid,
Form_pg_class  classForm,
AclMode  this_privileges,
AclMode col_privileges,
int  num_col_privileges 
)
static

Definition at line 1599 of file aclchk.c.

1603{
1605
1608 curr_att <= classForm->relnatts;
1609 curr_att++)
1610 {
1612 bool isdropped;
1613
1615 continue;
1616
1617 /* Views don't have any system columns at all */
1618 if (classForm->relkind == RELKIND_VIEW && curr_att < 0)
1619 continue;
1620
1625 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1627
1628 isdropped = ((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped;
1629
1631
1632 /* ignore dropped columns */
1633 if (isdropped)
1634 continue;
1635
1637 }
1638}
#define InvalidAttrNumber
Definition attnum.h:23
#define Assert(condition)
Definition c.h:943

References Assert, elog, ERROR, fb(), FirstLowInvalidHeapAttributeNumber, GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), InvalidAttrNumber, ObjectIdGetDatum(), ReleaseSysCache(), and SearchSysCache2().

Referenced by ExecGrant_Relation().

◆ expand_col_privileges()

static void expand_col_privileges ( List colnames,
Oid  table_oid,
AclMode  this_privileges,
AclMode col_privileges,
int  num_col_privileges 
)
static

Definition at line 1566 of file aclchk.c.

1570{
1571 ListCell *cell;
1572
1573 foreach(cell, colnames)
1574 {
1575 char *colname = strVal(lfirst(cell));
1577
1578 attnum = get_attnum(table_oid, colname);
1580 ereport(ERROR,
1582 errmsg("column \"%s\" of relation \"%s\" does not exist",
1583 colname, get_rel_name(table_oid))));
1586 elog(ERROR, "column number out of range"); /* safety check */
1588 }
1589}
char * get_rel_name(Oid relid)
Definition lsyscache.c:2159
AttrNumber get_attnum(Oid relid, const char *attname)
Definition lsyscache.c:1015
#define strVal(v)
Definition value.h:82

References attnum, elog, ereport, errcode(), errmsg, ERROR, fb(), FirstLowInvalidHeapAttributeNumber, get_attnum(), get_rel_name(), InvalidAttrNumber, lfirst, and strVal.

Referenced by ExecGrant_Relation().

◆ get_default_acl_internal()

static Acl * get_default_acl_internal ( Oid  roleId,
Oid  nsp_oid,
char  objtype 
)
static

Definition at line 4256 of file aclchk.c.

4257{
4258 Acl *result = NULL;
4259 HeapTuple tuple;
4260
4262 ObjectIdGetDatum(roleId),
4264 CharGetDatum(objtype));
4265
4266 if (HeapTupleIsValid(tuple))
4267 {
4269 bool isNull;
4270
4273 &isNull);
4274 if (!isNull)
4276 ReleaseSysCache(tuple);
4277 }
4278
4279 return result;
4280}
uint32 result
static Datum CharGetDatum(char X)
Definition postgres.h:132
HeapTuple SearchSysCache3(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3)
Definition syscache.c:241

References CharGetDatum(), DatumGetAclPCopy, fb(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), result, SearchSysCache3(), and SysCacheGetAttr().

Referenced by get_user_default_acl().

◆ get_user_default_acl()

Acl * get_user_default_acl ( ObjectType  objtype,
Oid  ownerId,
Oid  nsp_oid 
)

Definition at line 4291 of file aclchk.c.

4292{
4293 Acl *result;
4294 Acl *glob_acl;
4295 Acl *schema_acl;
4296 Acl *def_acl;
4297 char defaclobjtype;
4298
4299 /*
4300 * Use NULL during bootstrap, since pg_default_acl probably isn't there
4301 * yet.
4302 */
4304 return NULL;
4305
4306 /* Check if object type is supported in pg_default_acl */
4307 switch (objtype)
4308 {
4309 case OBJECT_TABLE:
4310 defaclobjtype = DEFACLOBJ_RELATION;
4311 break;
4312
4313 case OBJECT_SEQUENCE:
4314 defaclobjtype = DEFACLOBJ_SEQUENCE;
4315 break;
4316
4317 case OBJECT_FUNCTION:
4318 defaclobjtype = DEFACLOBJ_FUNCTION;
4319 break;
4320
4321 case OBJECT_TYPE:
4322 defaclobjtype = DEFACLOBJ_TYPE;
4323 break;
4324
4325 case OBJECT_SCHEMA:
4326 defaclobjtype = DEFACLOBJ_NAMESPACE;
4327 break;
4328
4329 case OBJECT_LARGEOBJECT:
4330 defaclobjtype = DEFACLOBJ_LARGEOBJECT;
4331 break;
4332
4333 default:
4334 return NULL;
4335 }
4336
4337 /* Look up the relevant pg_default_acl entries */
4338 glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4339 schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4340
4341 /* Quick out if neither entry exists */
4342 if (glob_acl == NULL && schema_acl == NULL)
4343 return NULL;
4344
4345 /* We need to know the hard-wired default value, too */
4346 def_acl = acldefault(objtype, ownerId);
4347
4348 /* If there's no global entry, substitute the hard-wired default */
4349 if (glob_acl == NULL)
4350 glob_acl = def_acl;
4351
4352 /* Merge in any per-schema privileges */
4353 result = aclmerge(glob_acl, schema_acl, ownerId);
4354
4355 /*
4356 * For efficiency, we want to return NULL if the result equals default.
4357 * This requires sorting both arrays to get an accurate comparison.
4358 */
4361 if (aclequal(result, def_acl))
4362 result = NULL;
4363
4364 return result;
4365}
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Definition acl.c:515
void aclitemsort(Acl *acl)
Definition acl.c:559
static Acl * get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype)
Definition aclchk.c:4256
#define IsBootstrapProcessingMode()
Definition miscadmin.h:495
#define InvalidOid

References acldefault(), aclequal(), aclitemsort(), aclmerge(), fb(), get_default_acl_internal(), InvalidOid, IsBootstrapProcessingMode, OBJECT_FUNCTION, OBJECT_LARGEOBJECT, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, and result.

Referenced by heap_create_with_catalog(), LargeObjectCreate(), NamespaceCreate(), ProcedureCreate(), and TypeCreate().

◆ getRelationsInNamespace()

static List * getRelationsInNamespace ( Oid  namespaceId,
char  relkind 
)
static

Definition at line 877 of file aclchk.c.

878{
879 List *relations = NIL;
880 ScanKeyData key[2];
881 Relation rel;
882 TableScanDesc scan;
883 HeapTuple tuple;
884
885 ScanKeyInit(&key[0],
889 ScanKeyInit(&key[1],
892 CharGetDatum(relkind));
893
895 scan = table_beginscan_catalog(rel, 2, key);
896
897 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
898 {
899 Oid oid = ((Form_pg_class) GETSTRUCT(tuple))->oid;
900
901 relations = lappend_oid(relations, oid);
902 }
903
904 table_endscan(scan);
906
907 return relations;
908}
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition heapam.c:1435
#define AccessShareLock
Definition lockdefs.h:36
@ ForwardScanDirection
Definition sdir.h:28
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, ScanKeyData *key)
Definition tableam.c:113
static void table_endscan(TableScanDesc scan)
Definition tableam.h:1061

References AccessShareLock, BTEqualStrategyNumber, CharGetDatum(), fb(), ForwardScanDirection, GETSTRUCT(), heap_getnext(), lappend_oid(), NIL, ObjectIdGetDatum(), ScanKeyInit(), table_beginscan_catalog(), table_close(), table_endscan(), and table_open().

Referenced by objectsInSchemaToOids().

◆ has_bypassrls_privilege()

bool has_bypassrls_privilege ( Oid  roleid)

Definition at line 4232 of file aclchk.c.

4233{
4234 bool result = false;
4236
4237 /* Superusers bypass all permission checking. */
4238 if (superuser_arg(roleid))
4239 return true;
4240
4243 {
4246 }
4247 return result;
4248}
END_CATALOG_STRUCT typedef FormData_pg_authid * Form_pg_authid
Definition pg_authid.h:60
bool rolbypassrls
Definition pg_authid.h:43
bool superuser_arg(Oid roleid)
Definition superuser.c:57

References fb(), Form_pg_authid, GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), result, rolbypassrls, SearchSysCache1(), and superuser_arg().

Referenced by AlterRole(), check_enable_rls(), CreateRole(), and RI_Initial_Check().

◆ has_createrole_privilege()

bool has_createrole_privilege ( Oid  roleid)

Definition at line 4213 of file aclchk.c.

4214{
4215 bool result = false;
4217
4218 /* Superusers bypass all permission checking. */
4219 if (superuser_arg(roleid))
4220 return true;
4221
4224 {
4227 }
4228 return result;
4229}
bool rolcreaterole
Definition pg_authid.h:39

References fb(), Form_pg_authid, GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), result, rolcreaterole, SearchSysCache1(), and superuser_arg().

Referenced by check_object_ownership(), CreateRole(), and have_createrole_privilege().

◆ merge_acl_with_grant()

static Acl * merge_acl_with_grant ( Acl old_acl,
bool  is_grant,
bool  grant_option,
DropBehavior  behavior,
List grantees,
AclMode  privileges,
Oid  grantorId,
Oid  ownerId 
)
static

Definition at line 182 of file aclchk.c.

186{
187 unsigned modechg;
188 ListCell *j;
189 Acl *new_acl;
190
192
194
195 foreach(j, grantees)
196 {
198 Acl *newer_acl;
199
200 aclitem.ai_grantee = lfirst_oid(j);
201
202 /*
203 * Grant options can only be granted to individual roles, not PUBLIC.
204 * The reason is that if a user would re-grant a privilege that he
205 * held through PUBLIC, and later the user is removed, the situation
206 * is impossible to clean up.
207 */
208 if (is_grant && grant_option && aclitem.ai_grantee == ACL_ID_PUBLIC)
211 errmsg("grant options can only be granted to roles")));
212
213 aclitem.ai_grantor = grantorId;
214
215 /*
216 * The asymmetry in the conditions here comes from the spec. In
217 * GRANT, the grant_option flag signals WITH GRANT OPTION, which means
218 * to grant both the basic privilege and its grant option. But in
219 * REVOKE, plain revoke revokes both the basic privilege and its grant
220 * option, while REVOKE GRANT OPTION revokes only the option.
221 */
223 (is_grant || !grant_option) ? privileges : ACL_NO_RIGHTS,
224 (!is_grant || grant_option) ? privileges : ACL_NO_RIGHTS);
225
226 newer_acl = aclupdate(new_acl, &aclitem, modechg, ownerId, behavior);
227
228 /* avoid memory leak when there are many grantees */
229 pfree(new_acl);
231 }
232
233 return new_acl;
234}
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Definition acl.c:1020
#define ACL_MODECHG_DEL
Definition acl.h:130
#define ACL_MODECHG_ADD
Definition acl.h:129
#define ACLITEM_SET_PRIVS_GOPTIONS(item, privs, goptions)
Definition acl.h:82
int j
Definition isn.c:78
Definition acl.h:55

References ACL_ID_PUBLIC, ACL_MODECHG_ADD, ACL_MODECHG_DEL, ACL_NO_RIGHTS, ACLITEM_SET_PRIVS_GOPTIONS, aclupdate(), ereport, errcode(), errmsg, ERROR, fb(), j, lfirst_oid, and pfree().

Referenced by ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), RemoveRoleFromInitPriv(), and SetDefaultACL().

◆ object_aclcheck()

AclResult object_aclcheck ( Oid  classid,
Oid  objectid,
Oid  roleid,
AclMode  mode 
)

Definition at line 3880 of file aclchk.c.

3881{
3882 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3883}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3890
static PgChecksumMode mode

References fb(), mode, and object_aclcheck_ext().

Referenced by AggregateCreate(), AlterExtensionNamespace(), AlterForeignServerOwner_internal(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepAlterColumnType(), ATPrepSetTableSpace(), BuildDescForRelation(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_temp_tablespaces(), CheckFunctionValidatorAccess(), CheckMyDatabase(), compute_return_type(), CreateCast(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), DropSubscription(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), extension_is_trusted(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), GetSubscription(), HandleFunctionRequest(), has_database_privilege_id_name(), has_database_privilege_name(), has_database_privilege_name_name(), has_foreign_data_wrapper_privilege_id_name(), has_foreign_data_wrapper_privilege_name(), has_foreign_data_wrapper_privilege_name_name(), has_function_privilege_id_name(), has_function_privilege_name(), has_function_privilege_name_name(), has_language_privilege_id_name(), has_language_privilege_name(), has_language_privilege_name_name(), has_schema_privilege_id_name(), has_schema_privilege_name(), has_schema_privilege_name_name(), has_server_privilege_id_name(), has_server_privilege_name(), has_server_privilege_name_name(), has_tablespace_privilege_id_name(), has_tablespace_privilege_name(), has_tablespace_privilege_name_name(), has_type_privilege_id_name(), has_type_privilege_name(), has_type_privilege_name_name(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), InitTempTableNamespace(), inline_function(), inline_function_in_from(), interpret_function_parameter_list(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), movedb(), pg_get_database_ddl_internal(), PrepareTempTablespaces(), preprocessNamespacePath(), RangeVarCallbackForAlterRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleInternal(), RenameSchema(), ri_CheckPermissions(), transformTableLikeClause(), user_mapping_ddl_aclcheck(), ValidateJoinEstimator(), and ValidateRestrictionEstimator().

◆ object_aclcheck_ext()

◆ object_aclmask()

static AclMode object_aclmask ( Oid  classid,
Oid  objectid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)
static

Definition at line 3072 of file aclchk.c.

3074{
3075 return object_aclmask_ext(classid, objectid, roleid, mask, how, NULL);
3076}

References fb(), and object_aclmask_ext().

Referenced by pg_aclmask().

◆ object_aclmask_ext()

static AclMode object_aclmask_ext ( Oid  classid,
Oid  objectid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
bool is_missing 
)
static

Definition at line 3083 of file aclchk.c.

3086{
3089 HeapTuple tuple;
3091 bool isNull;
3092 Acl *acl;
3093 Oid ownerId;
3094
3095 /* Special cases */
3096 switch (classid)
3097 {
3099 return pg_namespace_aclmask_ext(objectid, roleid, mask, how,
3100 is_missing);
3101 case TypeRelationId:
3102 return pg_type_aclmask_ext(objectid, roleid, mask, how,
3103 is_missing);
3104 }
3105
3106 /* Even more special cases */
3107 Assert(classid != RelationRelationId); /* should use pg_class_acl* */
3108 Assert(classid != LargeObjectMetadataRelationId); /* should use
3109 * pg_largeobject_acl* */
3110
3111 /* Superusers bypass all permission checking. */
3112 if (superuser_arg(roleid))
3113 return mask;
3114
3115 /*
3116 * Get the object's ACL from its catalog
3117 */
3118
3120
3122 if (!HeapTupleIsValid(tuple))
3123 {
3124 if (is_missing != NULL)
3125 {
3126 /* return "no privileges" instead of throwing an error */
3127 *is_missing = true;
3128 return 0;
3129 }
3130 else
3131 elog(ERROR, "cache lookup failed for %s %u",
3133 }
3134
3136 tuple,
3137 get_object_attnum_owner(classid)));
3138
3140 &isNull);
3141 if (isNull)
3142 {
3143 /* No ACL, so build default ACL */
3144 acl = acldefault(get_object_type(classid, objectid), ownerId);
3145 aclDatum = (Datum) 0;
3146 }
3147 else
3148 {
3149 /* detoast ACL if necessary */
3150 acl = DatumGetAclP(aclDatum);
3151 }
3152
3153 result = aclmask(acl, roleid, ownerId, mask, how);
3154
3155 /* if we have a detoasted copy, free it */
3156 if (acl && acl != DatumGetPointer(aclDatum))
3157 pfree(acl);
3158
3159 ReleaseSysCache(tuple);
3160
3161 return result;
3162}
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1416
#define DatumGetAclP(X)
Definition acl.h:120
static AclMode pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3652
static AclMode pg_type_aclmask_ext(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3754
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332

References acldefault(), aclmask(), Assert, DatumGetAclP, DatumGetObjectId(), DatumGetPointer(), elog, ERROR, fb(), get_object_attnum_acl(), get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), get_object_type(), HeapTupleIsValid, ObjectIdGetDatum(), pfree(), pg_namespace_aclmask_ext(), pg_type_aclmask_ext(), ReleaseSysCache(), result, SearchSysCache1(), superuser_arg(), SysCacheGetAttr(), and SysCacheGetAttrNotNull().

Referenced by object_aclcheck_ext(), and object_aclmask().

◆ object_ownercheck()

bool object_ownercheck ( Oid  classid,
Oid  objectid,
Oid  roleid 
)

Definition at line 4134 of file aclchk.c.

4135{
4137 Oid ownerId;
4138
4139 /* Superusers bypass all permission checking. */
4140 if (superuser_arg(roleid))
4141 return true;
4142
4143 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4144 if (classid == LargeObjectRelationId)
4146
4149 {
4150 /* we can get the object's tuple from the syscache */
4151 HeapTuple tuple;
4152
4154 if (!HeapTupleIsValid(tuple))
4155 elog(ERROR, "cache lookup failed for %s %u",
4157
4159 tuple,
4160 get_object_attnum_owner(classid)));
4161 ReleaseSysCache(tuple);
4162 }
4163 else
4164 {
4165 /* for catalogs without an appropriate syscache */
4166 Relation rel;
4167 ScanKeyData entry[1];
4168 SysScanDesc scan;
4169 HeapTuple tuple;
4170 bool isnull;
4171
4172 rel = table_open(classid, AccessShareLock);
4173
4174 ScanKeyInit(&entry[0],
4175 get_object_attnum_oid(classid),
4178
4179 scan = systable_beginscan(rel,
4180 get_object_oid_index(classid), true,
4181 NULL, 1, entry);
4182
4183 tuple = systable_getnext(scan);
4184 if (!HeapTupleIsValid(tuple))
4185 elog(ERROR, "could not find tuple for %s %u",
4187
4188 ownerId = DatumGetObjectId(heap_getattr(tuple,
4189 get_object_attnum_owner(classid),
4190 RelationGetDescr(rel),
4191 &isnull));
4192 Assert(!isnull);
4193
4194 systable_endscan(scan);
4196 }
4197
4198 return has_privs_of_role(roleid, ownerId);
4199}
AttrNumber get_object_attnum_oid(Oid class_id)
Oid get_object_oid_index(Oid class_id)

References AccessShareLock, Assert, BTEqualStrategyNumber, DatumGetObjectId(), elog, ERROR, fb(), get_object_attnum_oid(), get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), get_object_oid_index(), has_privs_of_role(), heap_getattr(), HeapTupleIsValid, ObjectIdGetDatum(), RelationGetDescr, ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), superuser_arg(), SysCacheGetAttrNotNull(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterType(), AlterTypeNamespace_oid(), AlterTypeOwner(), ATExecChangeOwner(), ATSimplePermissions(), be_lo_unlink(), brin_desummarize_range(), brin_summarize_range(), check_enable_rls(), check_object_ownership(), checkDomainOwner(), checkEnumOwner(), CreateCast(), createdb(), CreateProceduralLanguage(), CreateStatistics(), CreateTransform(), DefineOpClass(), DefineQueryRewrite(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecuteTruncateGuts(), gin_clean_pending_list(), heap_force_common(), MergeAttributes(), movedb(), OperatorCreate(), ProcedureCreate(), PublicationAddTables(), RangeVarCallbackForAlterRelation(), RangeVarCallbackForDropRelation(), RangeVarCallbackForPolicy(), RangeVarCallbackForRenameRule(), RangeVarCallbackForRenameTrigger(), RangeVarCallbackForStats(), RangeVarCallbackOwnsRelation(), RangeVarGetAndCheckCreationNamespace(), ReindexMultipleTables(), RemoveObjects(), renameatt_check(), RenameDatabase(), RenameSchema(), RenameTableSpace(), RenameType(), RI_Initial_Check(), user_mapping_ddl_aclcheck(), vacuum_is_permitted_for_relation(), and ValidateOperatorReference().

◆ objectNamesToOids()

static List * objectNamesToOids ( ObjectType  objtype,
List objnames,
bool  is_grant 
)
static

Definition at line 671 of file aclchk.c.

672{
673 List *objects = NIL;
674 ListCell *cell;
675 const LOCKMODE lockmode = AccessShareLock;
676
677 Assert(objnames != NIL);
678
679 switch (objtype)
680 {
681 default:
682
683 /*
684 * For most object types, we use get_object_address() directly.
685 */
686 foreach(cell, objnames)
687 {
688 ObjectAddress address;
689
690 address = get_object_address(objtype, lfirst(cell), NULL, lockmode, false);
691 objects = lappend_oid(objects, address.objectId);
692 }
693 break;
694
695 case OBJECT_TABLE:
696 case OBJECT_SEQUENCE:
697 case OBJECT_PROPGRAPH:
698
699 /*
700 * Here, we don't use get_object_address(). It requires that the
701 * specified object type match the actual type of the object, but
702 * in GRANT/REVOKE, all table-like things are addressed as TABLE.
703 */
704 foreach(cell, objnames)
705 {
706 RangeVar *relvar = (RangeVar *) lfirst(cell);
707 Oid relOid;
708
709 relOid = RangeVarGetRelid(relvar, lockmode, false);
710 objects = lappend_oid(objects, relOid);
711 }
712 break;
713
714 case OBJECT_DOMAIN:
715 case OBJECT_TYPE:
716
717 /*
718 * The parse representation of types and domains in privilege
719 * targets is different from that expected by get_object_address()
720 * (for parse conflict reasons), so we have to do a bit of
721 * conversion here.
722 */
723 foreach(cell, objnames)
724 {
725 List *typname = (List *) lfirst(cell);
727 ObjectAddress address;
728 Relation relation;
729
730 address = get_object_address(objtype, (Node *) tn, &relation, lockmode, false);
731 Assert(relation == NULL);
732 objects = lappend_oid(objects, address.objectId);
733 }
734 break;
735
737
738 /*
739 * Parameters are handled completely differently.
740 */
741 foreach(cell, objnames)
742 {
743 /*
744 * In this code we represent a GUC by the OID of its entry in
745 * pg_parameter_acl, which we have to manufacture here if it
746 * doesn't exist yet. (That's a hack for sure, but it avoids
747 * messing with all the GRANT/REVOKE infrastructure that
748 * expects to use OIDs for object identities.) However, if
749 * this is a REVOKE, we can instead just ignore any GUCs that
750 * don't have such an entry, as they must not have any
751 * privileges needing removal.
752 */
753 char *parameter = strVal(lfirst(cell));
755
756 if (!OidIsValid(parameterId) && is_grant)
757 {
759
760 /*
761 * Prevent error when processing duplicate objects, and
762 * make this new entry visible so that ExecGrant_Parameter
763 * can update it.
764 */
766 }
768 objects = lappend_oid(objects, parameterId);
769 }
770 break;
771 }
772
773 return objects;
774}
#define OidIsValid(objectId)
Definition c.h:858
int LOCKMODE
Definition lockdefs.h:26
TypeName * makeTypeNameFromNameList(List *names)
Definition makefuncs.c:531
#define RangeVarGetRelid(relation, lockmode, missing_ok)
Definition namespace.h:98
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
Oid ParameterAclLookup(const char *parameter, bool missing_ok)
Oid ParameterAclCreate(const char *parameter)
NameData typname
Definition pg_type.h:43
Definition nodes.h:135

References AccessShareLock, Assert, CommandCounterIncrement(), fb(), get_object_address(), lappend_oid(), lfirst, makeTypeNameFromNameList(), NIL, OBJECT_DOMAIN, OBJECT_PARAMETER_ACL, OBJECT_PROPGRAPH, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, ObjectAddress::objectId, OidIsValid, ParameterAclCreate(), ParameterAclLookup(), RangeVarGetRelid, strVal, and typname.

Referenced by ExecuteGrantStmt().

◆ objectsInSchemaToOids()

static List * objectsInSchemaToOids ( ObjectType  objtype,
List nspnames 
)
static

Definition at line 784 of file aclchk.c.

785{
786 List *objects = NIL;
787 ListCell *cell;
788
789 foreach(cell, nspnames)
790 {
791 char *nspname = strVal(lfirst(cell));
793 List *objs;
794
795 namespaceId = LookupExplicitNamespace(nspname, false);
796
797 switch (objtype)
798 {
799 case OBJECT_TABLE:
801 objects = list_concat(objects, objs);
803 objects = list_concat(objects, objs);
805 objects = list_concat(objects, objs);
807 objects = list_concat(objects, objs);
809 objects = list_concat(objects, objs);
810 break;
811 case OBJECT_SEQUENCE:
813 objects = list_concat(objects, objs);
814 break;
815 case OBJECT_PROPGRAPH:
817 objects = list_concat(objects, objs);
818 break;
819 case OBJECT_FUNCTION:
820 case OBJECT_PROCEDURE:
821 case OBJECT_ROUTINE:
822 {
823 ScanKeyData key[2];
824 int keycount;
825 Relation rel;
826 TableScanDesc scan;
827 HeapTuple tuple;
828
829 keycount = 0;
830 ScanKeyInit(&key[keycount++],
834
835 if (objtype == OBJECT_FUNCTION)
836 /* includes aggregates and window functions */
837 ScanKeyInit(&key[keycount++],
841 else if (objtype == OBJECT_PROCEDURE)
842 ScanKeyInit(&key[keycount++],
846
848 scan = table_beginscan_catalog(rel, keycount, key);
849
850 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
851 {
852 Oid oid = ((Form_pg_proc) GETSTRUCT(tuple))->oid;
853
854 objects = lappend_oid(objects, oid);
855 }
856
857 table_endscan(scan);
859 }
860 break;
861 default:
862 /* should not happen */
863 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
864 (int) objtype);
865 }
866 }
867
868 return objects;
869}
static List * getRelationsInNamespace(Oid namespaceId, char relkind)
Definition aclchk.c:877
List * list_concat(List *list1, const List *list2)
Definition list.c:561
Oid LookupExplicitNamespace(const char *nspname, bool missing_ok)
Definition namespace.c:3457
END_CATALOG_STRUCT typedef FormData_pg_proc * Form_pg_proc
Definition pg_proc.h:140

References AccessShareLock, BTEqualStrategyNumber, CharGetDatum(), elog, ERROR, fb(), Form_pg_proc, ForwardScanDirection, getRelationsInNamespace(), GETSTRUCT(), heap_getnext(), lappend_oid(), lfirst, list_concat(), LookupExplicitNamespace(), NIL, OBJECT_FUNCTION, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_ROUTINE, OBJECT_SEQUENCE, OBJECT_TABLE, ObjectIdGetDatum(), ScanKeyInit(), strVal, table_beginscan_catalog(), table_close(), table_endscan(), and table_open().

Referenced by ExecuteGrantStmt().

◆ pg_aclmask()

static AclMode pg_aclmask ( ObjectType  objtype,
Oid  object_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)
static

Definition at line 3009 of file aclchk.c.

3011{
3012 switch (objtype)
3013 {
3014 case OBJECT_COLUMN:
3015 return
3016 pg_class_aclmask(object_oid, roleid, mask, how) |
3017 pg_attribute_aclmask(object_oid, attnum, roleid, mask, how);
3018 case OBJECT_TABLE:
3019 case OBJECT_SEQUENCE:
3020 case OBJECT_PROPGRAPH:
3021 return pg_class_aclmask(object_oid, roleid, mask, how);
3022 case OBJECT_DATABASE:
3023 return object_aclmask(DatabaseRelationId, object_oid, roleid, mask, how);
3024 case OBJECT_FUNCTION:
3025 return object_aclmask(ProcedureRelationId, object_oid, roleid, mask, how);
3026 case OBJECT_LANGUAGE:
3027 return object_aclmask(LanguageRelationId, object_oid, roleid, mask, how);
3028 case OBJECT_LARGEOBJECT:
3030 mask, how, NULL);
3032 return pg_parameter_acl_aclmask(object_oid, roleid, mask, how);
3033 case OBJECT_SCHEMA:
3034 return object_aclmask(NamespaceRelationId, object_oid, roleid, mask, how);
3036 elog(ERROR, "grantable rights not supported for statistics objects");
3037 /* not reached, but keep compiler quiet */
3038 return ACL_NO_RIGHTS;
3039 case OBJECT_TABLESPACE:
3040 return object_aclmask(TableSpaceRelationId, object_oid, roleid, mask, how);
3041 case OBJECT_FDW:
3044 return object_aclmask(ForeignServerRelationId, object_oid, roleid, mask, how);
3046 elog(ERROR, "grantable rights not supported for event triggers");
3047 /* not reached, but keep compiler quiet */
3048 return ACL_NO_RIGHTS;
3049 case OBJECT_TYPE:
3050 return object_aclmask(TypeRelationId, object_oid, roleid, mask, how);
3051 default:
3052 elog(ERROR, "unrecognized object type: %d",
3053 (int) objtype);
3054 /* not reached, but keep compiler quiet */
3055 return ACL_NO_RIGHTS;
3056 }
3057}
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition aclchk.c:3561
static AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3173
static AclMode pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3502
static AclMode object_aclmask(Oid classid, Oid objectid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3072
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3298

References ACL_NO_RIGHTS, attnum, elog, ERROR, fb(), object_aclmask(), OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_EVENT_TRIGGER, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROPGRAPH, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, pg_attribute_aclmask(), pg_class_aclmask(), pg_largeobject_aclmask_snapshot(), and pg_parameter_acl_aclmask().

Referenced by restrict_and_check_grant().

◆ pg_attribute_aclcheck()

AclResult pg_attribute_aclcheck ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mode 
)

Definition at line 3912 of file aclchk.c.

3914{
3916}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3924

References attnum, fb(), mode, and pg_attribute_aclcheck_ext().

Referenced by all_rows_selectable(), BuildIndexValueDescription(), checkFkeyPermissions(), ExecBuildSlotPartitionKeyDescription(), ExecBuildSlotValueDescription(), ExecCheckOneRelPerms(), ExecCheckPermissionsModified(), and ri_ReportViolation().

◆ pg_attribute_aclcheck_all()

AclResult pg_attribute_aclcheck_all ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
AclMaskHow  how 
)

Definition at line 3954 of file aclchk.c.

3956{
3958}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3965

References fb(), mode, and pg_attribute_aclcheck_all_ext().

Referenced by all_rows_selectable(), ExecCheckOneRelPerms(), ExecCheckPermissionsModified(), has_any_column_privilege_id_name(), has_any_column_privilege_name(), and has_any_column_privilege_name_name().

◆ pg_attribute_aclcheck_all_ext()

AclResult pg_attribute_aclcheck_all_ext ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
AclMaskHow  how,
bool is_missing 
)

Definition at line 3965 of file aclchk.c.

3968{
3972 Oid ownerId;
3973 AttrNumber nattrs;
3975
3976 /*
3977 * Must fetch pg_class row to get owner ID and number of attributes.
3978 */
3981 {
3982 if (is_missing != NULL)
3983 {
3984 /* return "no privileges" instead of throwing an error */
3985 *is_missing = true;
3986 return ACLCHECK_NO_PRIV;
3987 }
3988 else
3989 ereport(ERROR,
3991 errmsg("relation with OID %u does not exist",
3992 table_oid)));
3993 }
3995
3996 ownerId = classForm->relowner;
3997 nattrs = classForm->relnatts;
3998
4000
4001 /*
4002 * Initialize result in case there are no non-dropped columns. We want to
4003 * report failure in such cases for either value of 'how'.
4004 */
4006
4007 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4008 {
4011 bool isNull;
4012 Acl *acl;
4014
4018
4019 /*
4020 * Lookup failure probably indicates that the table was just dropped,
4021 * but we'll treat it the same as a dropped column rather than
4022 * throwing error.
4023 */
4025 continue;
4026
4027 /* ignore dropped columns */
4028 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4029 {
4031 continue;
4032 }
4033
4035 &isNull);
4036
4037 /*
4038 * Here we hard-wire knowledge that the default ACL for a column
4039 * grants no privileges, so that we can fall out quickly in the very
4040 * common case where attacl is null.
4041 */
4042 if (isNull)
4043 attmask = 0;
4044 else
4045 {
4046 /* detoast column's ACL if necessary */
4047 acl = DatumGetAclP(aclDatum);
4048
4049 attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4050
4051 /* if we have a detoasted copy, free it */
4052 if (acl != DatumGetPointer(aclDatum))
4053 pfree(acl);
4054 }
4055
4057
4058 if (attmask != 0)
4059 {
4061 if (how == ACLMASK_ANY)
4062 break; /* succeed on any success */
4063 }
4064 else
4065 {
4067 if (how == ACLMASK_ALL)
4068 break; /* fail on any failure */
4069 }
4070 }
4071
4072 return result;
4073}
AclResult
Definition acl.h:183
@ ACLMASK_ALL
Definition acl.h:177
#define ERRCODE_UNDEFINED_TABLE
Definition pgbench.c:79

References ACLCHECK_NO_PRIV, ACLCHECK_OK, aclmask(), ACLMASK_ALL, ACLMASK_ANY, DatumGetAclP, DatumGetPointer(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg, ERROR, fb(), GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), mode, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), result, SearchSysCache1(), SearchSysCache2(), and SysCacheGetAttr().

Referenced by has_any_column_privilege_id(), has_any_column_privilege_id_id(), has_any_column_privilege_name_id(), and pg_attribute_aclcheck_all().

◆ pg_attribute_aclcheck_ext()

AclResult pg_attribute_aclcheck_ext ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mode,
bool is_missing 
)

Definition at line 3924 of file aclchk.c.

3926{
3928 ACLMASK_ANY, is_missing) != 0)
3929 return ACLCHECK_OK;
3930 else
3931 return ACLCHECK_NO_PRIV;
3932}
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3184

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, attnum, fb(), mode, and pg_attribute_aclmask_ext().

Referenced by column_privilege_check(), and pg_attribute_aclcheck().

◆ pg_attribute_aclmask()

static AclMode pg_attribute_aclmask ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)
static

Definition at line 3173 of file aclchk.c.

3175{
3177 mask, how, NULL);
3178}

References attnum, fb(), and pg_attribute_aclmask_ext().

Referenced by pg_aclmask().

◆ pg_attribute_aclmask_ext()

static AclMode pg_attribute_aclmask_ext ( Oid  table_oid,
AttrNumber  attnum,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
bool is_missing 
)
static

Definition at line 3184 of file aclchk.c.

3186{
3193 bool isNull;
3194 Acl *acl;
3195 Oid ownerId;
3196
3197 /*
3198 * First, get the column's ACL from its pg_attribute entry
3199 */
3204 {
3205 if (is_missing != NULL)
3206 {
3207 /* return "no privileges" instead of throwing an error */
3208 *is_missing = true;
3209 return 0;
3210 }
3211 else
3212 ereport(ERROR,
3214 errmsg("attribute %d of relation with OID %u does not exist",
3215 attnum, table_oid)));
3216 }
3217
3219
3220 /* Check dropped columns, too */
3221 if (attributeForm->attisdropped)
3222 {
3223 if (is_missing != NULL)
3224 {
3225 /* return "no privileges" instead of throwing an error */
3226 *is_missing = true;
3228 return 0;
3229 }
3230 else
3231 ereport(ERROR,
3233 errmsg("attribute %d of relation with OID %u does not exist",
3234 attnum, table_oid)));
3235 }
3236
3238 &isNull);
3239
3240 /*
3241 * Here we hard-wire knowledge that the default ACL for a column grants no
3242 * privileges, so that we can fall out quickly in the very common case
3243 * where attacl is null.
3244 */
3245 if (isNull)
3246 {
3248 return 0;
3249 }
3250
3251 /*
3252 * Must get the relation's ownerId from pg_class. Since we already found
3253 * a pg_attribute entry, the only likely reason for this to fail is that a
3254 * concurrent DROP of the relation committed since then (which could only
3255 * happen if we don't have lock on the relation). Treat that similarly to
3256 * not finding the attribute entry.
3257 */
3260 {
3262 if (is_missing != NULL)
3263 {
3264 /* return "no privileges" instead of throwing an error */
3265 *is_missing = true;
3266 return 0;
3267 }
3268 else
3269 ereport(ERROR,
3271 errmsg("relation with OID %u does not exist",
3272 table_oid)));
3273 }
3275
3276 ownerId = classForm->relowner;
3277
3279
3280 /* detoast column's ACL if necessary */
3281 acl = DatumGetAclP(aclDatum);
3282
3283 result = aclmask(acl, roleid, ownerId, mask, how);
3284
3285 /* if we have a detoasted copy, free it */
3286 if (acl && acl != DatumGetPointer(aclDatum))
3287 pfree(acl);
3288
3290
3291 return result;
3292}

References aclmask(), attnum, DatumGetAclP, DatumGetPointer(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg, ERROR, fb(), GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), ObjectIdGetDatum(), pfree(), ReleaseSysCache(), result, SearchSysCache1(), SearchSysCache2(), and SysCacheGetAttr().

Referenced by pg_attribute_aclcheck_ext(), and pg_attribute_aclmask().

◆ pg_class_aclcheck()

AclResult pg_class_aclcheck ( Oid  table_oid,
Oid  roleid,
AclMode  mode 
)

◆ pg_class_aclcheck_ext()

AclResult pg_class_aclcheck_ext ( Oid  table_oid,
Oid  roleid,
AclMode  mode,
bool is_missing 
)

◆ pg_class_aclmask()

AclMode pg_class_aclmask ( Oid  table_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)

Definition at line 3298 of file aclchk.c.

3300{
3301 return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3302}

References fb(), and pg_class_aclmask_ext().

Referenced by ExecCheckOneRelPerms(), and pg_aclmask().

◆ pg_class_aclmask_ext()

static AclMode pg_class_aclmask_ext ( Oid  table_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
bool is_missing 
)
static

Definition at line 3308 of file aclchk.c.

3310{
3312 HeapTuple tuple;
3315 bool isNull;
3316 Acl *acl;
3317 Oid ownerId;
3318
3319 /*
3320 * Must get the relation's tuple from pg_class
3321 */
3323 if (!HeapTupleIsValid(tuple))
3324 {
3325 if (is_missing != NULL)
3326 {
3327 /* return "no privileges" instead of throwing an error */
3328 *is_missing = true;
3329 return 0;
3330 }
3331 else
3332 ereport(ERROR,
3334 errmsg("relation with OID %u does not exist",
3335 table_oid)));
3336 }
3337
3339
3340 /*
3341 * Deny anyone permission to update a system catalog unless
3342 * pg_authid.rolsuper is set.
3343 *
3344 * As of 7.4 we have some updatable system views; those shouldn't be
3345 * protected in this way. Assume the view rules can take care of
3346 * themselves. ACL_USAGE is if we ever have system sequences.
3347 */
3348 if ((mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE | ACL_USAGE)) &&
3350 classForm->relkind != RELKIND_VIEW &&
3351 !superuser_arg(roleid))
3353
3354 /*
3355 * Otherwise, superusers bypass all permission-checking.
3356 */
3357 if (superuser_arg(roleid))
3358 {
3359 ReleaseSysCache(tuple);
3360 return mask;
3361 }
3362
3363 /*
3364 * Normal case: get the relation's ACL from pg_class
3365 */
3366 ownerId = classForm->relowner;
3367
3369 &isNull);
3370 if (isNull)
3371 {
3372 /* No ACL, so build default ACL */
3373 switch (classForm->relkind)
3374 {
3375 case RELKIND_SEQUENCE:
3376 acl = acldefault(OBJECT_SEQUENCE, ownerId);
3377 break;
3378 default:
3379 acl = acldefault(OBJECT_TABLE, ownerId);
3380 break;
3381 }
3382 aclDatum = (Datum) 0;
3383 }
3384 else
3385 {
3386 /* detoast rel's ACL if necessary */
3387 acl = DatumGetAclP(aclDatum);
3388 }
3389
3390 result = aclmask(acl, roleid, ownerId, mask, how);
3391
3392 /* if we have a detoasted copy, free it */
3393 if (acl && acl != DatumGetPointer(aclDatum))
3394 pfree(acl);
3395
3396 ReleaseSysCache(tuple);
3397
3398 /*
3399 * Check if ACL_SELECT is being checked and, if so, and not set already as
3400 * part of the result, then check if the user is a member of the
3401 * pg_read_all_data role, which allows read access to all relations.
3402 */
3403 if (mask & ACL_SELECT && !(result & ACL_SELECT) &&
3405 result |= ACL_SELECT;
3406
3407 /*
3408 * Check if ACL_INSERT, ACL_UPDATE, or ACL_DELETE is being checked and, if
3409 * so, and not set already as part of the result, then check if the user
3410 * is a member of the pg_write_all_data role, which allows
3411 * INSERT/UPDATE/DELETE access to all relations (except system catalogs,
3412 * which requires superuser, see above).
3413 */
3414 if (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE) &&
3417 result |= (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE));
3418
3419 /*
3420 * Check if ACL_MAINTAIN is being checked and, if so, and not already set
3421 * as part of the result, then check if the user is a member of the
3422 * pg_maintain role, which allows VACUUM, ANALYZE, CLUSTER, REFRESH
3423 * MATERIALIZED VIEW, REINDEX, and LOCK TABLE on all relations.
3424 */
3425 if (mask & ACL_MAINTAIN &&
3426 !(result & ACL_MAINTAIN) &&
3429
3430 return result;
3431}
bool IsSystemClass(Oid relid, Form_pg_class reltuple)
Definition catalog.c:86
#define ACL_DELETE
Definition parsenodes.h:79
#define ACL_MAINTAIN
Definition parsenodes.h:90
#define ACL_USAGE
Definition parsenodes.h:84
#define ACL_INSERT
Definition parsenodes.h:76
#define ACL_UPDATE
Definition parsenodes.h:78
#define ACL_TRUNCATE
Definition parsenodes.h:80

References ACL_DELETE, ACL_INSERT, ACL_MAINTAIN, ACL_SELECT, ACL_TRUNCATE, ACL_UPDATE, ACL_USAGE, acldefault(), aclmask(), DatumGetAclP, DatumGetPointer(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg, ERROR, fb(), GETSTRUCT(), has_privs_of_role(), HeapTupleIsValid, IsSystemClass(), OBJECT_SEQUENCE, OBJECT_TABLE, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), result, SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_class_aclcheck_ext(), and pg_class_aclmask().

◆ pg_largeobject_aclcheck_snapshot()

AclResult pg_largeobject_aclcheck_snapshot ( Oid  lobj_oid,
Oid  roleid,
AclMode  mode,
Snapshot  snapshot 
)

Definition at line 4120 of file aclchk.c.

4122{
4124 ACLMASK_ANY, snapshot) != 0)
4125 return ACLCHECK_OK;
4126 else
4127 return ACLCHECK_NO_PRIV;
4128}

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, fb(), mode, and pg_largeobject_aclmask_snapshot().

Referenced by has_lo_priv_byid(), and inv_open().

◆ pg_largeobject_aclmask_snapshot()

static AclMode pg_largeobject_aclmask_snapshot ( Oid  lobj_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
Snapshot  snapshot 
)
static

Definition at line 3561 of file aclchk.c.

3564{
3567 ScanKeyData entry[1];
3568 SysScanDesc scan;
3569 HeapTuple tuple;
3571 bool isNull;
3572 Acl *acl;
3573 Oid ownerId;
3574
3575 /* Superusers bypass all permission checking. */
3576 if (superuser_arg(roleid))
3577 return mask;
3578
3579 /*
3580 * Get the largeobject's ACL from pg_largeobject_metadata
3581 */
3584
3585 ScanKeyInit(&entry[0],
3589
3592 snapshot, 1, entry);
3593
3594 tuple = systable_getnext(scan);
3595 if (!HeapTupleIsValid(tuple))
3596 ereport(ERROR,
3598 errmsg("large object %u does not exist", lobj_oid)));
3599
3600 ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
3601
3603 RelationGetDescr(pg_lo_meta), &isNull);
3604
3605 if (isNull)
3606 {
3607 /* No ACL, so build default ACL */
3608 acl = acldefault(OBJECT_LARGEOBJECT, ownerId);
3609 aclDatum = (Datum) 0;
3610 }
3611 else
3612 {
3613 /* detoast ACL if necessary */
3614 acl = DatumGetAclP(aclDatum);
3615 }
3616
3617 result = aclmask(acl, roleid, ownerId, mask, how);
3618
3619 /* if we have a detoasted copy, free it */
3620 if (acl && acl != DatumGetPointer(aclDatum))
3621 pfree(acl);
3622
3623 systable_endscan(scan);
3624
3626
3627 /*
3628 * Check if ACL_SELECT is being checked and, if so, and not set already as
3629 * part of the result, then check if the user has privileges of the
3630 * pg_read_all_data role, which allows read access to all large objects.
3631 */
3632 if (mask & ACL_SELECT && !(result & ACL_SELECT) &&
3634 result |= ACL_SELECT;
3635
3636 /*
3637 * Check if ACL_UPDATE is being checked and, if so, and not set already as
3638 * part of the result, then check if the user has privileges of the
3639 * pg_write_all_data role, which allows write access to all large objects.
3640 */
3641 if (mask & ACL_UPDATE && !(result & ACL_UPDATE) &&
3643 result |= ACL_UPDATE;
3644
3645 return result;
3646}

References AccessShareLock, ACL_SELECT, ACL_UPDATE, acldefault(), aclmask(), BTEqualStrategyNumber, DatumGetAclP, DatumGetPointer(), ereport, errcode(), errmsg, ERROR, fb(), Form_pg_largeobject_metadata, GETSTRUCT(), has_privs_of_role(), heap_getattr(), HeapTupleIsValid, OBJECT_LARGEOBJECT, ObjectIdGetDatum(), pfree(), RelationGetDescr, result, ScanKeyInit(), superuser_arg(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by pg_aclmask(), and pg_largeobject_aclcheck_snapshot().

◆ pg_namespace_aclmask_ext()

static AclMode pg_namespace_aclmask_ext ( Oid  nsp_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
bool is_missing 
)
static

Definition at line 3652 of file aclchk.c.

3655{
3657 HeapTuple tuple;
3659 bool isNull;
3660 Acl *acl;
3661 Oid ownerId;
3662
3663 /* Superusers bypass all permission checking. */
3664 if (superuser_arg(roleid))
3665 return mask;
3666
3667 /*
3668 * If we have been assigned this namespace as a temp namespace, check to
3669 * make sure we have CREATE TEMP permission on the database, and if so act
3670 * as though we have all standard (but not GRANT OPTION) permissions on
3671 * the namespace. If we don't have CREATE TEMP, act as though we have
3672 * only USAGE (and not CREATE) rights.
3673 *
3674 * This may seem redundant given the check in InitTempTableNamespace, but
3675 * it really isn't since current user ID may have changed since then. The
3676 * upshot of this behavior is that a SECURITY DEFINER function can create
3677 * temp tables that can then be accessed (if permission is granted) by
3678 * code in the same session that doesn't have permissions to create temp
3679 * tables.
3680 *
3681 * XXX Would it be safe to ereport a special error message as
3682 * InitTempTableNamespace does? Returning zero here means we'll get a
3683 * generic "permission denied for schema pg_temp_N" message, which is not
3684 * remarkably user-friendly.
3685 */
3687 {
3690 return mask & ACL_ALL_RIGHTS_SCHEMA;
3691 else
3692 return mask & ACL_USAGE;
3693 }
3694
3695 /*
3696 * Get the schema's ACL from pg_namespace
3697 */
3699 if (!HeapTupleIsValid(tuple))
3700 {
3701 if (is_missing != NULL)
3702 {
3703 /* return "no privileges" instead of throwing an error */
3704 *is_missing = true;
3705 return 0;
3706 }
3707 else
3708 ereport(ERROR,
3710 errmsg("schema with OID %u does not exist", nsp_oid)));
3711 }
3712
3713 ownerId = ((Form_pg_namespace) GETSTRUCT(tuple))->nspowner;
3714
3716 &isNull);
3717 if (isNull)
3718 {
3719 /* No ACL, so build default ACL */
3720 acl = acldefault(OBJECT_SCHEMA, ownerId);
3721 aclDatum = (Datum) 0;
3722 }
3723 else
3724 {
3725 /* detoast ACL if necessary */
3726 acl = DatumGetAclP(aclDatum);
3727 }
3728
3729 result = aclmask(acl, roleid, ownerId, mask, how);
3730
3731 /* if we have a detoasted copy, free it */
3732 if (acl && acl != DatumGetPointer(aclDatum))
3733 pfree(acl);
3734
3735 ReleaseSysCache(tuple);
3736
3737 /*
3738 * Check if ACL_USAGE is being checked and, if so, and not set already as
3739 * part of the result, then check if the user is a member of the
3740 * pg_read_all_data or pg_write_all_data roles, which allow usage access
3741 * to all schemas.
3742 */
3743 if (mask & ACL_USAGE && !(result & ACL_USAGE) &&
3746 result |= ACL_USAGE;
3747 return result;
3748}
Oid MyDatabaseId
Definition globals.c:96
bool isTempNamespace(Oid namespaceId)
Definition namespace.c:3721
#define ACL_CREATE_TEMP
Definition parsenodes.h:86
END_CATALOG_STRUCT typedef FormData_pg_namespace * Form_pg_namespace

References ACL_ALL_RIGHTS_SCHEMA, ACL_CREATE_TEMP, ACL_USAGE, ACLCHECK_OK, acldefault(), aclmask(), DatumGetAclP, DatumGetPointer(), ereport, errcode(), errmsg, ERROR, fb(), Form_pg_namespace, GETSTRUCT(), has_privs_of_role(), HeapTupleIsValid, isTempNamespace(), MyDatabaseId, object_aclcheck_ext(), OBJECT_SCHEMA, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), result, SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by object_aclmask_ext().

◆ pg_parameter_acl_aclmask()

static AclMode pg_parameter_acl_aclmask ( Oid  acl_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)
static

Definition at line 3502 of file aclchk.c.

3503{
3505 HeapTuple tuple;
3507 bool isNull;
3508 Acl *acl;
3509
3510 /* Superusers bypass all permission checking. */
3511 if (superuser_arg(roleid))
3512 return mask;
3513
3514 /* Get the ACL from pg_parameter_acl */
3516 if (!HeapTupleIsValid(tuple))
3517 ereport(ERROR,
3519 errmsg("parameter ACL with OID %u does not exist",
3520 acl_oid)));
3521
3524 &isNull);
3525 if (isNull)
3526 {
3527 /* No ACL, so build default ACL */
3529 aclDatum = (Datum) 0;
3530 }
3531 else
3532 {
3533 /* detoast ACL if necessary */
3534 acl = DatumGetAclP(aclDatum);
3535 }
3536
3537 result = aclmask(acl, roleid, BOOTSTRAP_SUPERUSERID, mask, how);
3538
3539 /* if we have a detoasted copy, free it */
3540 if (acl && acl != DatumGetPointer(aclDatum))
3541 pfree(acl);
3542
3543 ReleaseSysCache(tuple);
3544
3545 return result;
3546}

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer(), ereport, errcode(), errmsg, ERROR, fb(), HeapTupleIsValid, OBJECT_PARAMETER_ACL, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), result, SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_aclmask().

◆ pg_parameter_aclcheck()

AclResult pg_parameter_aclcheck ( const char name,
Oid  roleid,
AclMode  mode 
)

Definition at line 4108 of file aclchk.c.

4109{
4110 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4111 return ACLCHECK_OK;
4112 else
4113 return ACLCHECK_NO_PRIV;
4114}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3438
const char * name

References ACLCHECK_NO_PRIV, ACLCHECK_OK, ACLMASK_ANY, mode, name, and pg_parameter_aclmask().

Referenced by AlterSystemSetConfigFile(), has_param_priv_byname(), set_config_with_handle(), and validate_option_array_item().

◆ pg_parameter_aclmask()

static AclMode pg_parameter_aclmask ( const char name,
Oid  roleid,
AclMode  mask,
AclMaskHow  how 
)
static

Definition at line 3438 of file aclchk.c.

3439{
3441 char *parname;
3442 text *partext;
3443 HeapTuple tuple;
3444
3445 /* Superusers bypass all permission checking. */
3446 if (superuser_arg(roleid))
3447 return mask;
3448
3449 /* Convert name to the form it should have in pg_parameter_acl... */
3452
3453 /* ... and look it up */
3455
3456 if (!HeapTupleIsValid(tuple))
3457 {
3458 /* If no entry, GUC has no permissions for non-superusers */
3460 }
3461 else
3462 {
3464 bool isNull;
3465 Acl *acl;
3466
3469 &isNull);
3470 if (isNull)
3471 {
3472 /* No ACL, so build default ACL */
3474 aclDatum = (Datum) 0;
3475 }
3476 else
3477 {
3478 /* detoast ACL if necessary */
3479 acl = DatumGetAclP(aclDatum);
3480 }
3481
3482 result = aclmask(acl, roleid, BOOTSTRAP_SUPERUSERID, mask, how);
3483
3484 /* if we have a detoasted copy, free it */
3485 if (acl && acl != DatumGetPointer(aclDatum))
3486 pfree(acl);
3487
3488 ReleaseSysCache(tuple);
3489 }
3490
3491 pfree(parname);
3492 pfree(partext);
3493
3494 return result;
3495}
char * convert_GUC_name_for_parameter_acl(const char *name)
Definition guc.c:1252
Definition c.h:776
text * cstring_to_text(const char *s)
Definition varlena.c:184

References ACL_NO_RIGHTS, acldefault(), aclmask(), convert_GUC_name_for_parameter_acl(), cstring_to_text(), DatumGetAclP, DatumGetPointer(), fb(), HeapTupleIsValid, name, OBJECT_PARAMETER_ACL, pfree(), PointerGetDatum, ReleaseSysCache(), result, SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by pg_parameter_aclcheck().

◆ pg_type_aclmask_ext()

static AclMode pg_type_aclmask_ext ( Oid  type_oid,
Oid  roleid,
AclMode  mask,
AclMaskHow  how,
bool is_missing 
)
static

Definition at line 3754 of file aclchk.c.

3756{
3758 HeapTuple tuple;
3761 bool isNull;
3762 Acl *acl;
3763 Oid ownerId;
3764
3765 /* Bypass permission checks for superusers */
3766 if (superuser_arg(roleid))
3767 return mask;
3768
3769 /*
3770 * Must get the type's tuple from pg_type
3771 */
3773 if (!HeapTupleIsValid(tuple))
3774 {
3775 if (is_missing != NULL)
3776 {
3777 /* return "no privileges" instead of throwing an error */
3778 *is_missing = true;
3779 return 0;
3780 }
3781 else
3782 ereport(ERROR,
3784 errmsg("type with OID %u does not exist",
3785 type_oid)));
3786 }
3787 typeForm = (Form_pg_type) GETSTRUCT(tuple);
3788
3789 /*
3790 * "True" array types don't manage permissions of their own; consult the
3791 * element type instead.
3792 */
3794 {
3795 Oid elttype_oid = typeForm->typelem;
3796
3797 ReleaseSysCache(tuple);
3798
3800 if (!HeapTupleIsValid(tuple))
3801 {
3802 if (is_missing != NULL)
3803 {
3804 /* return "no privileges" instead of throwing an error */
3805 *is_missing = true;
3806 return 0;
3807 }
3808 else
3809 ereport(ERROR,
3811 errmsg("type with OID %u does not exist",
3812 elttype_oid)));
3813 }
3814 typeForm = (Form_pg_type) GETSTRUCT(tuple);
3815 }
3816
3817 /*
3818 * Likewise, multirange types don't manage their own permissions; consult
3819 * the associated range type. (Note we must do this after the array step
3820 * to get the right answer for arrays of multiranges.)
3821 */
3822 if (typeForm->typtype == TYPTYPE_MULTIRANGE)
3823 {
3825
3826 ReleaseSysCache(tuple);
3827
3829 if (!HeapTupleIsValid(tuple))
3830 {
3831 if (is_missing != NULL)
3832 {
3833 /* return "no privileges" instead of throwing an error */
3834 *is_missing = true;
3835 return 0;
3836 }
3837 else
3838 ereport(ERROR,
3840 errmsg("type with OID %u does not exist",
3841 rangetype)));
3842 }
3843 typeForm = (Form_pg_type) GETSTRUCT(tuple);
3844 }
3845
3846 /*
3847 * Now get the type's owner and ACL from the tuple
3848 */
3849 ownerId = typeForm->typowner;
3850
3852 Anum_pg_type_typacl, &isNull);
3853 if (isNull)
3854 {
3855 /* No ACL, so build default ACL */
3856 acl = acldefault(OBJECT_TYPE, ownerId);
3857 aclDatum = (Datum) 0;
3858 }
3859 else
3860 {
3861 /* detoast rel's ACL if necessary */
3862 acl = DatumGetAclP(aclDatum);
3863 }
3864
3865 result = aclmask(acl, roleid, ownerId, mask, how);
3866
3867 /* if we have a detoasted copy, free it */
3868 if (acl && acl != DatumGetPointer(aclDatum))
3869 pfree(acl);
3870
3871 ReleaseSysCache(tuple);
3872
3873 return result;
3874}
Oid get_multirange_range(Oid multirangeOid)
Definition lsyscache.c:3761

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer(), ereport, errcode(), errmsg, ERROR, fb(), Form_pg_type, get_multirange_range(), GETSTRUCT(), HeapTupleIsValid, OBJECT_TYPE, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), result, SearchSysCache1(), superuser_arg(), and SysCacheGetAttr().

Referenced by object_aclmask_ext().

◆ privilege_to_string()

static const char * privilege_to_string ( AclMode  privilege)
static

Definition at line 2625 of file aclchk.c.

2626{
2627 switch (privilege)
2628 {
2629 case ACL_INSERT:
2630 return "INSERT";
2631 case ACL_SELECT:
2632 return "SELECT";
2633 case ACL_UPDATE:
2634 return "UPDATE";
2635 case ACL_DELETE:
2636 return "DELETE";
2637 case ACL_TRUNCATE:
2638 return "TRUNCATE";
2639 case ACL_REFERENCES:
2640 return "REFERENCES";
2641 case ACL_TRIGGER:
2642 return "TRIGGER";
2643 case ACL_EXECUTE:
2644 return "EXECUTE";
2645 case ACL_USAGE:
2646 return "USAGE";
2647 case ACL_CREATE:
2648 return "CREATE";
2649 case ACL_CREATE_TEMP:
2650 return "TEMP";
2651 case ACL_CONNECT:
2652 return "CONNECT";
2653 case ACL_SET:
2654 return "SET";
2655 case ACL_ALTER_SYSTEM:
2656 return "ALTER SYSTEM";
2657 case ACL_MAINTAIN:
2658 return "MAINTAIN";
2659 default:
2660 elog(ERROR, "unrecognized privilege: %d", (int) privilege);
2661 }
2662 return NULL; /* appease compiler */
2663}
#define ACL_SET
Definition parsenodes.h:88
#define ACL_CONNECT
Definition parsenodes.h:87
#define ACL_ALTER_SYSTEM
Definition parsenodes.h:89
#define ACL_REFERENCES
Definition parsenodes.h:81
#define ACL_EXECUTE
Definition parsenodes.h:83
#define ACL_CREATE
Definition parsenodes.h:85
#define ACL_TRIGGER
Definition parsenodes.h:82

References ACL_ALTER_SYSTEM, ACL_CONNECT, ACL_CREATE, ACL_CREATE_TEMP, ACL_DELETE, ACL_EXECUTE, ACL_INSERT, ACL_MAINTAIN, ACL_REFERENCES, ACL_SELECT, ACL_SET, ACL_TRIGGER, ACL_TRUNCATE, ACL_UPDATE, ACL_USAGE, elog, ERROR, and fb().

Referenced by ExecAlterDefaultPrivilegesStmt(), ExecGrant_Relation(), and ExecuteGrantStmt().

◆ recordDependencyOnNewAcl()

void recordDependencyOnNewAcl ( Oid  classId,
Oid  objectId,
int32  objsubId,
Oid  ownerId,
Acl acl 
)

Definition at line 4371 of file aclchk.c.

4373{
4374 int nmembers;
4375 Oid *members;
4376
4377 /* Nothing to do if ACL is defaulted */
4378 if (acl == NULL)
4379 return;
4380
4381 /* Extract roles mentioned in ACL */
4382 nmembers = aclmembers(acl, &members);
4383
4384 /* Update the shared dependency ACL info */
4385 updateAclDependencies(classId, objectId, objsubId,
4386 ownerId,
4387 0, NULL,
4388 nmembers, members);
4389}

References aclmembers(), fb(), and updateAclDependencies().

Referenced by GenerateTypeDependencies(), heap_create_with_catalog(), LargeObjectCreate(), NamespaceCreate(), and ProcedureCreate().

◆ recordExtensionInitPriv()

static void recordExtensionInitPriv ( Oid  objoid,
Oid  classoid,
int  objsubid,
Acl new_acl 
)
static

Definition at line 4645 of file aclchk.c.

4646{
4647 /*
4648 * Generally, we only record the initial privileges when an extension is
4649 * being created, but because we don't actually use CREATE EXTENSION
4650 * during binary upgrades with pg_upgrade, there is a variable to let us
4651 * know that the GRANT and REVOKE statements being issued, while this
4652 * variable is true, are for the initial privileges of the extension
4653 * object and therefore we need to record them.
4654 */
4656 return;
4657
4658 recordExtensionInitPrivWorker(objoid, classoid, objsubid, new_acl);
4659}
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition aclchk.c:4674
bool binary_upgrade_record_init_privs
Definition aclchk.c:110
bool creating_extension
Definition extension.c:80

References binary_upgrade_record_init_privs, creating_extension, fb(), and recordExtensionInitPrivWorker().

Referenced by ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), and ExecGrant_Relation().

◆ recordExtensionInitPrivWorker()

static void recordExtensionInitPrivWorker ( Oid  objoid,
Oid  classoid,
int  objsubid,
Acl new_acl 
)
static

Definition at line 4674 of file aclchk.c.

4676{
4677 Relation relation;
4678 ScanKeyData key[3];
4679 SysScanDesc scan;
4680 HeapTuple tuple;
4681 HeapTuple oldtuple;
4682 int noldmembers;
4683 int nnewmembers;
4684 Oid *oldmembers;
4685 Oid *newmembers;
4686
4687 /* We'll need the role membership of the new ACL. */
4689
4690 /* Search pg_init_privs for an existing entry. */
4692
4693 ScanKeyInit(&key[0],
4696 ObjectIdGetDatum(objoid));
4697 ScanKeyInit(&key[1],
4700 ObjectIdGetDatum(classoid));
4701 ScanKeyInit(&key[2],
4704 Int32GetDatum(objsubid));
4705
4706 scan = systable_beginscan(relation, InitPrivsObjIndexId, true,
4707 NULL, 3, key);
4708
4709 /* There should exist only one entry or none. */
4710 oldtuple = systable_getnext(scan);
4711
4712 /* If we find an entry, update it with the latest ACL. */
4713 if (HeapTupleIsValid(oldtuple))
4714 {
4716 bool nulls[Natts_pg_init_privs] = {0};
4717 bool replace[Natts_pg_init_privs] = {0};
4719 bool isNull;
4720 Acl *old_acl;
4721
4722 /* Update pg_shdepend for roles mentioned in the old/new ACLs. */
4724 RelationGetDescr(relation), &isNull);
4725 Assert(!isNull);
4728
4729 updateInitAclDependencies(classoid, objoid, objsubid,
4732
4733 /* If we have a new ACL to set, then update the row with it. */
4734 if (new_acl && ACL_NUM(new_acl) != 0)
4735 {
4737 replace[Anum_pg_init_privs_initprivs - 1] = true;
4738
4739 oldtuple = heap_modify_tuple(oldtuple, RelationGetDescr(relation),
4740 values, nulls, replace);
4741
4742 CatalogTupleUpdate(relation, &oldtuple->t_self, oldtuple);
4743 }
4744 else
4745 {
4746 /* new_acl is NULL/empty, so delete the entry we found. */
4747 CatalogTupleDelete(relation, &oldtuple->t_self);
4748 }
4749 }
4750 else
4751 {
4753 bool nulls[Natts_pg_init_privs] = {0};
4754
4755 /*
4756 * Only add a new entry if the new ACL is non-NULL.
4757 *
4758 * If we are passed in a NULL ACL and no entry exists, we can just
4759 * fall through and do nothing.
4760 */
4761 if (new_acl && ACL_NUM(new_acl) != 0)
4762 {
4763 /* No entry found, so add it. */
4767
4768 /* This function only handles initial privileges of extensions */
4771
4773
4774 tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
4775
4776 CatalogTupleInsert(relation, tuple);
4777
4778 /* Update pg_shdepend, too. */
4779 noldmembers = 0;
4780 oldmembers = NULL;
4781
4782 updateInitAclDependencies(classoid, objoid, objsubid,
4785 }
4786 }
4787
4788 systable_endscan(scan);
4789
4790 /* prevent error when processing objects multiple times */
4792
4793 table_close(relation, RowExclusiveLock);
4794}
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1025
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
@ INITPRIVS_EXTENSION
void updateInitAclDependencies(Oid classId, Oid objectId, int32 objsubId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212

References ACL_NUM, aclmembers(), Assert, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), CharGetDatum(), CommandCounterIncrement(), DatumGetAclP, fb(), heap_form_tuple(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, INITPRIVS_EXTENSION, Int32GetDatum(), ObjectIdGetDatum(), PointerGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), updateInitAclDependencies(), and values.

Referenced by recordExtensionInitPriv(), recordExtObjInitPriv(), and removeExtObjInitPriv().

◆ recordExtObjInitPriv()

void recordExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4398 of file aclchk.c.

4399{
4400 /*
4401 * pg_class / pg_attribute
4402 *
4403 * If this is a relation then we need to see if there are any sub-objects
4404 * (eg: columns) for it and, if so, be sure to call
4405 * recordExtensionInitPrivWorker() for each one.
4406 */
4407 if (classoid == RelationRelationId)
4408 {
4411 bool isNull;
4412 HeapTuple tuple;
4413
4414 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4415 if (!HeapTupleIsValid(tuple))
4416 elog(ERROR, "cache lookup failed for relation %u", objoid);
4418
4419 /*
4420 * Indexes don't have permissions, neither do the pg_class rows for
4421 * composite types. (These cases are unreachable given the
4422 * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4423 */
4424 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4427 {
4428 ReleaseSysCache(tuple);
4429 return;
4430 }
4431
4432 /*
4433 * If this isn't a sequence then it's possibly going to have
4434 * column-level ACLs associated with it.
4435 */
4436 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4437 {
4439 AttrNumber nattrs = pg_class_tuple->relnatts;
4440
4441 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4442 {
4445
4447 ObjectIdGetDatum(objoid),
4449
4451 continue;
4452
4453 /* ignore dropped columns */
4454 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4455 {
4457 continue;
4458 }
4459
4462 &isNull);
4463
4464 /* no need to do anything for a NULL ACL */
4465 if (isNull)
4466 {
4468 continue;
4469 }
4470
4471 recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4473
4475 }
4476 }
4477
4479 &isNull);
4480
4481 /* Add the record, if any, for the top-level object */
4482 if (!isNull)
4483 recordExtensionInitPrivWorker(objoid, classoid, 0,
4485
4486 ReleaseSysCache(tuple);
4487 }
4488 else if (classoid == LargeObjectRelationId)
4489 {
4490 /* For large objects, we must consult pg_largeobject_metadata */
4492 bool isNull;
4493 HeapTuple tuple;
4494 ScanKeyData entry[1];
4495 SysScanDesc scan;
4496 Relation relation;
4497
4498 /*
4499 * Note: this is dead code, given that we don't allow large objects to
4500 * be made extension members. But it seems worth carrying in case
4501 * some future caller of this function has need for it.
4502 */
4504
4505 /* There's no syscache for pg_largeobject_metadata */
4506 ScanKeyInit(&entry[0],
4509 ObjectIdGetDatum(objoid));
4510
4511 scan = systable_beginscan(relation,
4513 NULL, 1, entry);
4514
4515 tuple = systable_getnext(scan);
4516 if (!HeapTupleIsValid(tuple))
4517 elog(ERROR, "could not find tuple for large object %u", objoid);
4518
4519 aclDatum = heap_getattr(tuple,
4521 RelationGetDescr(relation), &isNull);
4522
4523 /* Add the record, if any, for the top-level object */
4524 if (!isNull)
4525 recordExtensionInitPrivWorker(objoid, classoid, 0,
4527
4528 systable_endscan(scan);
4529 }
4530 /* This will error on unsupported classoid. */
4531 else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4532 {
4535 bool isNull;
4536 HeapTuple tuple;
4537
4538 cacheid = get_object_catcache_oid(classoid);
4539 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objoid));
4540 if (!HeapTupleIsValid(tuple))
4541 elog(ERROR, "cache lookup failed for %s %u",
4542 get_object_class_descr(classoid), objoid);
4543
4545 get_object_attnum_acl(classoid),
4546 &isNull);
4547
4548 /* Add the record, if any, for the top-level object */
4549 if (!isNull)
4550 recordExtensionInitPrivWorker(objoid, classoid, 0,
4552
4553 ReleaseSysCache(tuple);
4554 }
4555}

References BTEqualStrategyNumber, DatumGetAclP, elog, ERROR, fb(), get_object_attnum_acl(), get_object_catcache_oid(), get_object_class_descr(), GETSTRUCT(), heap_getattr(), HeapTupleIsValid, Int16GetDatum(), InvalidAttrNumber, ObjectIdGetDatum(), recordExtensionInitPrivWorker(), RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), SearchSysCache2(), SysCacheGetAttr(), systable_beginscan(), systable_endscan(), systable_getnext(), and table_open().

Referenced by ExecAlterExtensionContentsRecurse().

◆ removeExtObjInitPriv()

void removeExtObjInitPriv ( Oid  objoid,
Oid  classoid 
)

Definition at line 4562 of file aclchk.c.

4563{
4564 /*
4565 * If this is a relation then we need to see if there are any sub-objects
4566 * (eg: columns) for it and, if so, be sure to call
4567 * recordExtensionInitPrivWorker() for each one.
4568 */
4569 if (classoid == RelationRelationId)
4570 {
4572 HeapTuple tuple;
4573
4574 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4575 if (!HeapTupleIsValid(tuple))
4576 elog(ERROR, "cache lookup failed for relation %u", objoid);
4578
4579 /*
4580 * Indexes don't have permissions, neither do the pg_class rows for
4581 * composite types. (These cases are unreachable given the
4582 * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4583 */
4584 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4587 {
4588 ReleaseSysCache(tuple);
4589 return;
4590 }
4591
4592 /*
4593 * If this isn't a sequence then it's possibly going to have
4594 * column-level ACLs associated with it.
4595 */
4596 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4597 {
4599 AttrNumber nattrs = pg_class_tuple->relnatts;
4600
4601 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4602 {
4604
4606 ObjectIdGetDatum(objoid),
4608
4610 continue;
4611
4612 /* when removing, remove all entries, even dropped columns */
4613
4614 recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4615
4617 }
4618 }
4619
4620 ReleaseSysCache(tuple);
4621 }
4622
4623 /* Remove the record, if any, for the top-level object */
4624 recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4625}

References elog, ERROR, fb(), GETSTRUCT(), HeapTupleIsValid, Int16GetDatum(), ObjectIdGetDatum(), recordExtensionInitPrivWorker(), ReleaseSysCache(), SearchSysCache1(), and SearchSysCache2().

Referenced by ExecAlterExtensionContentsRecurse().

◆ RemoveRoleFromInitPriv()

void RemoveRoleFromInitPriv ( Oid  roleid,
Oid  classid,
Oid  objid,
int32  objsubid 
)

Definition at line 4911 of file aclchk.c.

4912{
4913 Relation rel;
4914 ScanKeyData key[3];
4915 SysScanDesc scan;
4916 HeapTuple oldtuple;
4919 Oid ownerId;
4921 bool isNull;
4922 Acl *old_acl;
4923 Acl *new_acl;
4924 HeapTuple newtuple;
4925 int noldmembers;
4926 int nnewmembers;
4927 Oid *oldmembers;
4928 Oid *newmembers;
4929
4930 /* Search for existing pg_init_privs entry for the target object. */
4932
4933 ScanKeyInit(&key[0],
4936 ObjectIdGetDatum(objid));
4937 ScanKeyInit(&key[1],
4940 ObjectIdGetDatum(classid));
4941 ScanKeyInit(&key[2],
4944 Int32GetDatum(objsubid));
4945
4946 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4947 NULL, 3, key);
4948
4949 /* There should exist only one entry or none. */
4950 oldtuple = systable_getnext(scan);
4951
4952 if (!HeapTupleIsValid(oldtuple))
4953 {
4954 /*
4955 * Hmm, why are we here if there's no entry? But pack up and go away
4956 * quietly.
4957 */
4958 systable_endscan(scan);
4960 return;
4961 }
4962
4963 /* Get a writable copy of the existing ACL. */
4965 RelationGetDescr(rel), &isNull);
4966 Assert(!isNull);
4968
4969 /*
4970 * We need the members of both old and new ACLs so we can correct the
4971 * shared dependency information. Collect data before
4972 * merge_acl_with_grant throws away old_acl.
4973 */
4975
4976 /* Must find out the owner's OID the hard way. */
4980 elog(ERROR, "cache lookup failed for %s %u",
4981 get_object_class_descr(classid), objid);
4982
4984 objtuple,
4985 get_object_attnum_owner(classid)));
4987
4988 /*
4989 * Generate new ACL. Grantor of rights is always the same as the owner.
4990 */
4991 if (old_acl != NULL)
4993 false, /* is_grant */
4994 false, /* grant_option */
4996 list_make1_oid(roleid),
4998 ownerId,
4999 ownerId);
5000 else
5001 new_acl = NULL; /* this case shouldn't happen, probably */
5002
5003 /* If we end with an empty ACL, delete the pg_init_privs entry. */
5004 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
5005 {
5006 CatalogTupleDelete(rel, &oldtuple->t_self);
5007 }
5008 else
5009 {
5011 bool nulls[Natts_pg_init_privs] = {0};
5012 bool replaces[Natts_pg_init_privs] = {0};
5013
5014 /* Update existing entry. */
5017
5018 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
5019 values, nulls, replaces);
5020 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
5021 }
5022
5023 /*
5024 * Update the shared dependency ACL info.
5025 */
5027
5028 updateInitAclDependencies(classid, objid, objsubid,
5031
5032 systable_endscan(scan);
5033
5034 /* prevent error when processing objects multiple times */
5036
5038}
#define ACLITEM_ALL_PRIV_BITS
Definition acl.h:87
@ DROP_RESTRICT
#define list_make1_oid(x1)
Definition pg_list.h:274

References ACL_NUM, ACLITEM_ALL_PRIV_BITS, aclmembers(), Assert, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, DatumGetObjectId(), DROP_RESTRICT, elog, ERROR, fb(), get_object_attnum_owner(), get_object_catcache_oid(), get_object_class_descr(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, Int32GetDatum(), list_make1_oid, merge_acl_with_grant(), ObjectIdGetDatum(), PointerGetDatum, RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, ScanKeyInit(), SearchSysCache1(), SysCacheGetAttrNotNull(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), updateInitAclDependencies(), and values.

Referenced by shdepDropOwned().

◆ RemoveRoleFromObjectACL()

void RemoveRoleFromObjectACL ( Oid  roleid,
Oid  classid,
Oid  objid 
)

Definition at line 1426 of file aclchk.c.

1427{
1428 if (classid == DefaultAclRelationId)
1429 {
1432 Relation rel;
1433 ScanKeyData skey[1];
1434 SysScanDesc scan;
1435 HeapTuple tuple;
1436
1437 /* first fetch info needed by SetDefaultACL */
1439
1440 ScanKeyInit(&skey[0],
1443 ObjectIdGetDatum(objid));
1444
1445 scan = systable_beginscan(rel, DefaultAclOidIndexId, true,
1446 NULL, 1, skey);
1447
1448 tuple = systable_getnext(scan);
1449
1450 if (!HeapTupleIsValid(tuple))
1451 elog(ERROR, "could not find tuple for default ACL %u", objid);
1452
1454
1455 iacls.roleid = pg_default_acl_tuple->defaclrole;
1456 iacls.nspid = pg_default_acl_tuple->defaclnamespace;
1457
1458 switch (pg_default_acl_tuple->defaclobjtype)
1459 {
1460 case DEFACLOBJ_RELATION:
1461 iacls.objtype = OBJECT_TABLE;
1462 break;
1463 case DEFACLOBJ_SEQUENCE:
1464 iacls.objtype = OBJECT_SEQUENCE;
1465 break;
1466 case DEFACLOBJ_FUNCTION:
1467 iacls.objtype = OBJECT_FUNCTION;
1468 break;
1469 case DEFACLOBJ_TYPE:
1470 iacls.objtype = OBJECT_TYPE;
1471 break;
1473 iacls.objtype = OBJECT_SCHEMA;
1474 break;
1476 iacls.objtype = OBJECT_LARGEOBJECT;
1477 break;
1478 default:
1479 /* Shouldn't get here */
1480 elog(ERROR, "unexpected default ACL type: %d",
1481 (int) pg_default_acl_tuple->defaclobjtype);
1482 break;
1483 }
1484
1485 systable_endscan(scan);
1487
1488 iacls.is_grant = false;
1489 iacls.all_privs = true;
1490 iacls.privileges = ACL_NO_RIGHTS;
1491 iacls.grantees = list_make1_oid(roleid);
1492 iacls.grant_option = false;
1493 iacls.grantor = NULL;
1494 iacls.behavior = DROP_CASCADE;
1495
1496 /* Do it */
1498 }
1499 else
1500 {
1501 InternalGrant istmt;
1502
1503 switch (classid)
1504 {
1505 case RelationRelationId:
1506 /* it's OK to use TABLE for a sequence */
1507 istmt.objtype = OBJECT_TABLE;
1508 break;
1509 case DatabaseRelationId:
1510 istmt.objtype = OBJECT_DATABASE;
1511 break;
1512 case TypeRelationId:
1513 istmt.objtype = OBJECT_TYPE;
1514 break;
1516 istmt.objtype = OBJECT_ROUTINE;
1517 break;
1518 case LanguageRelationId:
1519 istmt.objtype = OBJECT_LANGUAGE;
1520 break;
1523 break;
1525 istmt.objtype = OBJECT_SCHEMA;
1526 break;
1528 istmt.objtype = OBJECT_TABLESPACE;
1529 break;
1532 break;
1534 istmt.objtype = OBJECT_FDW;
1535 break;
1538 break;
1539 default:
1540 elog(ERROR, "unexpected object class %u", classid);
1541 break;
1542 }
1543 istmt.is_grant = false;
1544 istmt.objects = list_make1_oid(objid);
1545 istmt.all_privs = true;
1546 istmt.privileges = ACL_NO_RIGHTS;
1547 istmt.col_privs = NIL;
1548 istmt.grantees = list_make1_oid(roleid);
1549 istmt.grant_option = false;
1550 istmt.grantor = NULL;
1551 istmt.behavior = DROP_CASCADE;
1552
1553 ExecGrantStmt_oids(&istmt);
1554 }
1555}
static void SetDefaultACL(InternalDefaultACL *iacls)
Definition aclchk.c:1151
@ DROP_CASCADE
END_CATALOG_STRUCT typedef FormData_pg_default_acl * Form_pg_default_acl

References AccessShareLock, ACL_NO_RIGHTS, InternalGrant::all_privs, InternalGrant::behavior, BTEqualStrategyNumber, InternalGrant::col_privs, DROP_CASCADE, elog, ERROR, ExecGrantStmt_oids(), fb(), Form_pg_default_acl, GETSTRUCT(), InternalGrant::grant_option, InternalGrant::grantees, InternalGrant::grantor, HeapTupleIsValid, InternalGrant::is_grant, list_make1_oid, NIL, OBJECT_DATABASE, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_ROUTINE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, ObjectIdGetDatum(), InternalGrant::objects, InternalGrant::objtype, InternalGrant::privileges, ScanKeyInit(), SetDefaultACL(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by shdepDropOwned().

◆ ReplaceRoleInInitPriv()

void ReplaceRoleInInitPriv ( Oid  oldroleid,
Oid  newroleid,
Oid  classid,
Oid  objid,
int32  objsubid 
)

Definition at line 4802 of file aclchk.c.

4804{
4805 Relation rel;
4806 ScanKeyData key[3];
4807 SysScanDesc scan;
4808 HeapTuple oldtuple;
4810 bool isNull;
4811 Acl *old_acl;
4812 Acl *new_acl;
4813 HeapTuple newtuple;
4814 int noldmembers;
4815 int nnewmembers;
4816 Oid *oldmembers;
4817 Oid *newmembers;
4818
4819 /* Search for existing pg_init_privs entry for the target object. */
4821
4822 ScanKeyInit(&key[0],
4825 ObjectIdGetDatum(objid));
4826 ScanKeyInit(&key[1],
4829 ObjectIdGetDatum(classid));
4830 ScanKeyInit(&key[2],
4833 Int32GetDatum(objsubid));
4834
4835 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4836 NULL, 3, key);
4837
4838 /* There should exist only one entry or none. */
4839 oldtuple = systable_getnext(scan);
4840
4841 if (!HeapTupleIsValid(oldtuple))
4842 {
4843 /*
4844 * Hmm, why are we here if there's no entry? But pack up and go away
4845 * quietly.
4846 */
4847 systable_endscan(scan);
4849 return;
4850 }
4851
4852 /* Get a writable copy of the existing ACL. */
4854 RelationGetDescr(rel), &isNull);
4855 Assert(!isNull);
4857
4858 /*
4859 * Generate new ACL. This usage of aclnewowner is a bit off-label when
4860 * oldroleid isn't the owner; but it does the job fine.
4861 */
4863
4864 /*
4865 * If we end with an empty ACL, delete the pg_init_privs entry. (That
4866 * probably can't happen here, but we may as well cover the case.)
4867 */
4868 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4869 {
4870 CatalogTupleDelete(rel, &oldtuple->t_self);
4871 }
4872 else
4873 {
4875 bool nulls[Natts_pg_init_privs] = {0};
4876 bool replaces[Natts_pg_init_privs] = {0};
4877
4878 /* Update existing entry. */
4881
4882 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4883 values, nulls, replaces);
4884 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4885 }
4886
4887 /*
4888 * Update the shared dependency ACL info.
4889 */
4892
4893 updateInitAclDependencies(classid, objid, objsubid,
4896
4897 systable_endscan(scan);
4898
4899 /* prevent error when processing objects multiple times */
4901
4903}
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1147

References ACL_NUM, aclmembers(), aclnewowner(), Assert, BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, fb(), heap_getattr(), heap_modify_tuple(), HeapTupleIsValid, Int32GetDatum(), ObjectIdGetDatum(), PointerGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), updateInitAclDependencies(), and values.

Referenced by shdepReassignOwned_InitAcl().

◆ restrict_and_check_grant()

static AclMode restrict_and_check_grant ( bool  is_grant,
AclMode  avail_goptions,
bool  all_privs,
AclMode  privileges,
Oid  objectId,
Oid  grantorId,
ObjectType  objtype,
const char objname,
AttrNumber  att_number,
const char colname 
)
static

Definition at line 241 of file aclchk.c.

245{
248
249 switch (objtype)
250 {
251 case OBJECT_COLUMN:
253 break;
254 case OBJECT_TABLE:
256 break;
257 case OBJECT_SEQUENCE:
259 break;
260 case OBJECT_DATABASE:
262 break;
263 case OBJECT_FUNCTION:
265 break;
266 case OBJECT_LANGUAGE:
268 break;
271 break;
272 case OBJECT_SCHEMA:
274 break;
277 break;
278 case OBJECT_FDW:
280 break;
283 break;
285 elog(ERROR, "grantable rights not supported for event triggers");
286 /* not reached, but keep compiler quiet */
287 return ACL_NO_RIGHTS;
288 case OBJECT_TYPE:
290 break;
293 break;
294 case OBJECT_PROPGRAPH:
296 break;
297 default:
298 elog(ERROR, "unrecognized object type: %d", objtype);
299 /* not reached, but keep compiler quiet */
300 return ACL_NO_RIGHTS;
301 }
302
303 /*
304 * If we found no grant options, consider whether to issue a hard error.
305 * Per spec, having any privilege at all on the object will get you by
306 * here.
307 */
309 {
310 if (pg_aclmask(objtype, objectId, att_number, grantorId,
313 {
314 if (objtype == OBJECT_COLUMN && colname)
315 aclcheck_error_col(ACLCHECK_NO_PRIV, objtype, objname, colname);
316 else
317 aclcheck_error(ACLCHECK_NO_PRIV, objtype, objname);
318 }
319 }
320
321 /*
322 * Restrict the operation to what we can actually grant or revoke, and
323 * issue a warning if appropriate. (For REVOKE this isn't quite what the
324 * spec says to do: the spec seems to want a warning only if no privilege
325 * bits actually change in the ACL. In practice that behavior seems much
326 * too noisy, as well as inconsistent with the GRANT case.)
327 */
329 if (is_grant)
330 {
331 if (this_privileges == 0)
332 {
333 if (objtype == OBJECT_COLUMN && colname)
336 errmsg("no privileges were granted for column \"%s\" of relation \"%s\"",
337 colname, objname)));
338 else
341 errmsg("no privileges were granted for \"%s\"",
342 objname)));
343 }
344 else if (!all_privs && this_privileges != privileges)
345 {
346 if (objtype == OBJECT_COLUMN && colname)
349 errmsg("not all privileges were granted for column \"%s\" of relation \"%s\"",
350 colname, objname)));
351 else
354 errmsg("not all privileges were granted for \"%s\"",
355 objname)));
356 }
357 }
358 else
359 {
360 if (this_privileges == 0)
361 {
362 if (objtype == OBJECT_COLUMN && colname)
365 errmsg("no privileges could be revoked for column \"%s\" of relation \"%s\"",
366 colname, objname)));
367 else
370 errmsg("no privileges could be revoked for \"%s\"",
371 objname)));
372 }
373 else if (!all_privs && this_privileges != privileges)
374 {
375 if (objtype == OBJECT_COLUMN && colname)
378 errmsg("not all privileges could be revoked for column \"%s\" of relation \"%s\"",
379 colname, objname)));
380 else
383 errmsg("not all privileges could be revoked for \"%s\"",
384 objname)));
385 }
386 }
387
388 return this_privileges;
389}
#define ACL_OPTION_TO_PRIVS(privs)
Definition acl.h:71
#define ACL_GRANT_OPTION_FOR(privs)
Definition acl.h:70
void aclcheck_error_col(AclResult aclerr, ObjectType objtype, const char *objectname, const char *colname)
Definition aclchk.c:2967
static AclMode pg_aclmask(ObjectType objtype, Oid object_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3009

References ACL_ALL_RIGHTS_COLUMN, ACL_ALL_RIGHTS_DATABASE, ACL_ALL_RIGHTS_FDW, ACL_ALL_RIGHTS_FOREIGN_SERVER, ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LANGUAGE, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_ALL_RIGHTS_PROPGRAPH, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TABLESPACE, ACL_ALL_RIGHTS_TYPE, ACL_GRANT_OPTION_FOR, ACL_NO_RIGHTS, ACL_OPTION_TO_PRIVS, aclcheck_error(), aclcheck_error_col(), ACLCHECK_NO_PRIV, ACLMASK_ANY, elog, ereport, errcode(), errmsg, ERROR, fb(), OBJECT_COLUMN, OBJECT_DATABASE, OBJECT_EVENT_TRIGGER, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FUNCTION, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_PARAMETER_ACL, OBJECT_PROPGRAPH, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TYPE, pg_aclmask(), and WARNING.

Referenced by ExecGrant_Attribute(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), and ExecGrant_Relation().

◆ SetDefaultACL()

static void SetDefaultACL ( InternalDefaultACL iacls)
static

Definition at line 1151 of file aclchk.c.

1152{
1153 AclMode this_privileges = iacls->privileges;
1154 char objtype;
1155 Relation rel;
1156 HeapTuple tuple;
1157 bool isNew;
1158 Acl *def_acl;
1159 Acl *old_acl;
1160 Acl *new_acl;
1161 HeapTuple newtuple;
1162 int noldmembers;
1163 int nnewmembers;
1164 Oid *oldmembers;
1165 Oid *newmembers;
1166
1168
1169 /*
1170 * The default for a global entry is the hard-wired default ACL for the
1171 * particular object type. The default for non-global entries is an empty
1172 * ACL. This must be so because global entries replace the hard-wired
1173 * defaults, while others are added on.
1174 */
1175 if (!OidIsValid(iacls->nspid))
1176 def_acl = acldefault(iacls->objtype, iacls->roleid);
1177 else
1179
1180 /*
1181 * Convert ACL object type to pg_default_acl object type and handle
1182 * all_privs option
1183 */
1184 switch (iacls->objtype)
1185 {
1186 case OBJECT_TABLE:
1187 objtype = DEFACLOBJ_RELATION;
1188 if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS)
1190 break;
1191
1192 case OBJECT_SEQUENCE:
1193 objtype = DEFACLOBJ_SEQUENCE;
1194 if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS)
1196 break;
1197
1198 case OBJECT_FUNCTION:
1199 objtype = DEFACLOBJ_FUNCTION;
1200 if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS)
1202 break;
1203
1204 case OBJECT_TYPE:
1205 objtype = DEFACLOBJ_TYPE;
1206 if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS)
1208 break;
1209
1210 case OBJECT_SCHEMA:
1211 if (OidIsValid(iacls->nspid))
1212 ereport(ERROR,
1214 errmsg("cannot use IN SCHEMA clause when using %s",
1215 "GRANT/REVOKE ON SCHEMAS")));
1216 objtype = DEFACLOBJ_NAMESPACE;
1217 if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS)
1219 break;
1220
1221 case OBJECT_LARGEOBJECT:
1222 if (OidIsValid(iacls->nspid))
1223 ereport(ERROR,
1225 errmsg("cannot use IN SCHEMA clause when using %s",
1226 "GRANT/REVOKE ON LARGE OBJECTS")));
1227 objtype = DEFACLOBJ_LARGEOBJECT;
1228 if (iacls->all_privs && this_privileges == ACL_NO_RIGHTS)
1230 break;
1231
1232 default:
1233 elog(ERROR, "unrecognized object type: %d",
1234 (int) iacls->objtype);
1235 objtype = 0; /* keep compiler quiet */
1236 break;
1237 }
1238
1239 /* Search for existing row for this object type in catalog */
1241 ObjectIdGetDatum(iacls->roleid),
1242 ObjectIdGetDatum(iacls->nspid),
1243 CharGetDatum(objtype));
1244
1245 if (HeapTupleIsValid(tuple))
1246 {
1248 bool isNull;
1249
1252 &isNull);
1253 if (!isNull)
1255 else
1256 old_acl = NULL; /* this case shouldn't happen, probably */
1257 isNew = false;
1258 }
1259 else
1260 {
1261 old_acl = NULL;
1262 isNew = true;
1263 }
1264
1265 if (old_acl != NULL)
1266 {
1267 /*
1268 * We need the members of both old and new ACLs so we can correct the
1269 * shared dependency information. Collect data before
1270 * merge_acl_with_grant throws away old_acl.
1271 */
1273 }
1274 else
1275 {
1276 /* If no or null entry, start with the default ACL value */
1278 /* There are no old member roles according to the catalogs */
1279 noldmembers = 0;
1280 oldmembers = NULL;
1281 }
1282
1283 /*
1284 * Generate new ACL. Grantor of rights is always the same as the target
1285 * role.
1286 */
1288 iacls->is_grant,
1289 iacls->grant_option,
1290 iacls->behavior,
1291 iacls->grantees,
1293 iacls->roleid,
1294 iacls->roleid);
1295
1296 /*
1297 * If the result is the same as the default value, we do not need an
1298 * explicit pg_default_acl entry, and should in fact remove the entry if
1299 * it exists. Must sort both arrays to compare properly.
1300 */
1303 if (aclequal(new_acl, def_acl))
1304 {
1305 /* delete old entry, if indeed there is one */
1306 if (!isNew)
1307 {
1309
1310 /*
1311 * The dependency machinery will take care of removing all
1312 * associated dependency entries. We use DROP_RESTRICT since
1313 * there shouldn't be anything depending on this entry.
1314 */
1316 myself.objectId = ((Form_pg_default_acl) GETSTRUCT(tuple))->oid;
1317 myself.objectSubId = 0;
1318
1320 }
1321 }
1322 else
1323 {
1325 bool nulls[Natts_pg_default_acl] = {0};
1326 bool replaces[Natts_pg_default_acl] = {0};
1327 Oid defAclOid;
1328
1329 if (isNew)
1330 {
1331 /* insert new entry */
1339
1340 newtuple = heap_form_tuple(RelationGetDescr(rel), values, nulls);
1341 CatalogTupleInsert(rel, newtuple);
1342 }
1343 else
1344 {
1345 defAclOid = ((Form_pg_default_acl) GETSTRUCT(tuple))->oid;
1346
1347 /* update existing entry */
1350
1351 newtuple = heap_modify_tuple(tuple, RelationGetDescr(rel),
1352 values, nulls, replaces);
1353 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
1354 }
1355
1356 /* these dependencies don't change in an update */
1357 if (isNew)
1358 {
1359 /* dependency on role */
1361 iacls->roleid);
1362
1363 /* dependency on namespace */
1364 if (OidIsValid(iacls->nspid))
1365 {
1367 referenced;
1368
1370 myself.objectId = defAclOid;
1371 myself.objectSubId = 0;
1372
1374 referenced.objectId = iacls->nspid;
1375 referenced.objectSubId = 0;
1376
1378 }
1379 }
1380
1381 /*
1382 * Update the shared dependency ACL info
1383 */
1385
1387 defAclOid, 0,
1388 iacls->roleid,
1391
1392 if (isNew)
1394 else
1396 }
1397
1398 if (HeapTupleIsValid(tuple))
1399 ReleaseSysCache(tuple);
1400
1402
1403 /* prevent error when processing duplicate objects */
1405}
Acl * make_empty_acl(void)
Definition acl.c:462
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition catalog.c:448
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition dependency.c:279
@ DEPENDENCY_AUTO
Definition dependency.h:34
#define InvokeObjectPostCreateHook(classId, objectId, subId)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition pg_depend.c:47
void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)

References ACL_ALL_RIGHTS_FUNCTION, ACL_ALL_RIGHTS_LARGEOBJECT, ACL_ALL_RIGHTS_RELATION, ACL_ALL_RIGHTS_SCHEMA, ACL_ALL_RIGHTS_SEQUENCE, ACL_ALL_RIGHTS_TYPE, ACL_NO_RIGHTS, aclcopy(), acldefault(), aclequal(), aclitemsort(), aclmembers(), CatalogTupleInsert(), CatalogTupleUpdate(), CharGetDatum(), ObjectAddress::classId, CommandCounterIncrement(), DatumGetAclPCopy, DEPENDENCY_AUTO, DROP_RESTRICT, elog, ereport, errcode(), errmsg, ERROR, fb(), Form_pg_default_acl, GetNewOidWithIndex(), GETSTRUCT(), heap_form_tuple(), heap_modify_tuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, InvokeObjectPostCreateHook, make_empty_acl(), merge_acl_with_grant(), OBJECT_FUNCTION, OBJECT_LARGEOBJECT, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_TABLE, OBJECT_TYPE, ObjectIdGetDatum(), OidIsValid, performDeletion(), PointerGetDatum, recordDependencyOn(), recordDependencyOnOwner(), RelationGetDescr, ReleaseSysCache(), RowExclusiveLock, SearchSysCache3(), SysCacheGetAttr(), HeapTupleData::t_self, table_close(), table_open(), updateAclDependencies(), and values.

Referenced by RemoveRoleFromObjectACL(), and SetDefaultACLsInSchemas().

◆ SetDefaultACLsInSchemas()

static void SetDefaultACLsInSchemas ( InternalDefaultACL iacls,
List nspnames 
)
static

Definition at line 1109 of file aclchk.c.

1110{
1111 if (nspnames == NIL)
1112 {
1113 /* Set database-wide permissions if no schema was specified */
1114 iacls->nspid = InvalidOid;
1115
1117 }
1118 else
1119 {
1120 /* Look up the schema OIDs and set permissions for each one */
1122
1123 foreach(nspcell, nspnames)
1124 {
1125 char *nspname = strVal(lfirst(nspcell));
1126
1127 iacls->nspid = get_namespace_oid(nspname, false);
1128
1129 /*
1130 * We used to insist that the target role have CREATE privileges
1131 * on the schema, since without that it wouldn't be able to create
1132 * an object for which these default privileges would apply.
1133 * However, this check proved to be more confusing than helpful,
1134 * and it also caused certain database states to not be
1135 * dumpable/restorable, since revoking CREATE doesn't cause
1136 * default privileges for the schema to go away. So now, we just
1137 * allow the ALTER; if the user lacks CREATE he'll find out when
1138 * he tries to create an object.
1139 */
1140
1142 }
1143 }
1144}
Oid get_namespace_oid(const char *nspname, bool missing_ok)
Definition namespace.c:3607

References fb(), get_namespace_oid(), InvalidOid, lfirst, NIL, SetDefaultACL(), and strVal.

Referenced by ExecAlterDefaultPrivilegesStmt().

◆ string_to_privilege()

static AclMode string_to_privilege ( const char privname)
static

Definition at line 2584 of file aclchk.c.

2585{
2586 if (strcmp(privname, "insert") == 0)
2587 return ACL_INSERT;
2588 if (strcmp(privname, "select") == 0)
2589 return ACL_SELECT;
2590 if (strcmp(privname, "update") == 0)
2591 return ACL_UPDATE;
2592 if (strcmp(privname, "delete") == 0)
2593 return ACL_DELETE;
2594 if (strcmp(privname, "truncate") == 0)
2595 return ACL_TRUNCATE;
2596 if (strcmp(privname, "references") == 0)
2597 return ACL_REFERENCES;
2598 if (strcmp(privname, "trigger") == 0)
2599 return ACL_TRIGGER;
2600 if (strcmp(privname, "execute") == 0)
2601 return ACL_EXECUTE;
2602 if (strcmp(privname, "usage") == 0)
2603 return ACL_USAGE;
2604 if (strcmp(privname, "create") == 0)
2605 return ACL_CREATE;
2606 if (strcmp(privname, "temporary") == 0)
2607 return ACL_CREATE_TEMP;
2608 if (strcmp(privname, "temp") == 0)
2609 return ACL_CREATE_TEMP;
2610 if (strcmp(privname, "connect") == 0)
2611 return ACL_CONNECT;
2612 if (strcmp(privname, "set") == 0)
2613 return ACL_SET;
2614 if (strcmp(privname, "alter system") == 0)
2615 return ACL_ALTER_SYSTEM;
2616 if (strcmp(privname, "maintain") == 0)
2617 return ACL_MAINTAIN;
2618 ereport(ERROR,
2620 errmsg("unrecognized privilege type \"%s\"", privname)));
2621 return 0; /* appease compiler */
2622}

References ACL_ALTER_SYSTEM, ACL_CONNECT, ACL_CREATE, ACL_CREATE_TEMP, ACL_DELETE, ACL_EXECUTE, ACL_INSERT, ACL_MAINTAIN, ACL_REFERENCES, ACL_SELECT, ACL_SET, ACL_TRIGGER, ACL_TRUNCATE, ACL_UPDATE, ACL_USAGE, ereport, errcode(), errmsg, ERROR, and fb().

Referenced by ExecAlterDefaultPrivilegesStmt(), ExecGrant_Relation(), and ExecuteGrantStmt().

Variable Documentation

◆ binary_upgrade_record_init_privs

bool binary_upgrade_record_init_privs = false

Definition at line 110 of file aclchk.c.

Referenced by binary_upgrade_set_record_init_privs(), and recordExtensionInitPriv().