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:1325
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(), createPartitionTable(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), 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:5317
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5642
#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:427
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:1571
void select_best_grantor(const RoleSpec *grantedBy, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
Definition acl.c:5511
#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:4667
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:894
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:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:515
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:1002

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:2242
AttrNumber get_attnum(Oid relid, const char *attname)
Definition lsyscache.c:1084
#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 4278 of file aclchk.c.

4279{
4280 Acl *result = NULL;
4281 HeapTuple tuple;
4282
4284 ObjectIdGetDatum(roleId),
4286 CharGetDatum(objtype));
4287
4288 if (HeapTupleIsValid(tuple))
4289 {
4291 bool isNull;
4292
4295 &isNull);
4296 if (!isNull)
4298 ReleaseSysCache(tuple);
4299 }
4300
4301 return result;
4302}
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 4313 of file aclchk.c.

4314{
4315 Acl *result;
4316 Acl *glob_acl;
4317 Acl *schema_acl;
4318 Acl *def_acl;
4319 char defaclobjtype;
4320
4321 /*
4322 * Use NULL during bootstrap, since pg_default_acl probably isn't there
4323 * yet.
4324 */
4326 return NULL;
4327
4328 /* Check if object type is supported in pg_default_acl */
4329 switch (objtype)
4330 {
4331 case OBJECT_TABLE:
4332 defaclobjtype = DEFACLOBJ_RELATION;
4333 break;
4334
4335 case OBJECT_SEQUENCE:
4336 defaclobjtype = DEFACLOBJ_SEQUENCE;
4337 break;
4338
4339 case OBJECT_FUNCTION:
4340 defaclobjtype = DEFACLOBJ_FUNCTION;
4341 break;
4342
4343 case OBJECT_TYPE:
4344 defaclobjtype = DEFACLOBJ_TYPE;
4345 break;
4346
4347 case OBJECT_SCHEMA:
4348 defaclobjtype = DEFACLOBJ_NAMESPACE;
4349 break;
4350
4351 case OBJECT_LARGEOBJECT:
4352 defaclobjtype = DEFACLOBJ_LARGEOBJECT;
4353 break;
4354
4355 default:
4356 return NULL;
4357 }
4358
4359 /* Look up the relevant pg_default_acl entries */
4360 glob_acl = get_default_acl_internal(ownerId, InvalidOid, defaclobjtype);
4361 schema_acl = get_default_acl_internal(ownerId, nsp_oid, defaclobjtype);
4362
4363 /* Quick out if neither entry exists */
4364 if (glob_acl == NULL && schema_acl == NULL)
4365 return NULL;
4366
4367 /* We need to know the hard-wired default value, too */
4368 def_acl = acldefault(objtype, ownerId);
4369
4370 /* If there's no global entry, substitute the hard-wired default */
4371 if (glob_acl == NULL)
4372 glob_acl = def_acl;
4373
4374 /* Merge in any per-schema privileges */
4375 result = aclmerge(glob_acl, schema_acl, ownerId);
4376
4377 /*
4378 * For efficiency, we want to return NULL if the result equals default.
4379 * This requires sorting both arrays to get an accurate comparison.
4380 */
4383 if (aclequal(result, def_acl))
4384 result = NULL;
4385
4386 return result;
4387}
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:4278
#define IsBootstrapProcessingMode()
Definition miscadmin.h:486
#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:1436
#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 4254 of file aclchk.c.

4255{
4256 bool result = false;
4258
4259 /* Superusers bypass all permission checking. */
4260 if (superuser_arg(roleid))
4261 return true;
4262
4265 {
4268 }
4269 return result;
4270}
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 4235 of file aclchk.c.

4236{
4237 bool result = false;
4239
4240 /* Superusers bypass all permission checking. */
4241 if (superuser_arg(roleid))
4242 return true;
4243
4246 {
4249 }
4250 return result;
4251}
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:1023
#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 3902 of file aclchk.c.

3903{
3904 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3905}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3912
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(), construct_subserver_conninfo(), CreateCast(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), createPartitionTable(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateTransform(), CreateTriggerFiringOn(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), 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:1419
#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:3666
static AclMode pg_type_aclmask_ext(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3776
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 4156 of file aclchk.c.

4157{
4159 Oid ownerId;
4160
4161 /* Superusers bypass all permission checking. */
4162 if (superuser_arg(roleid))
4163 return true;
4164
4165 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4166 if (classid == LargeObjectRelationId)
4168
4171 {
4172 /* we can get the object's tuple from the syscache */
4173 HeapTuple tuple;
4174
4176 if (!HeapTupleIsValid(tuple))
4177 elog(ERROR, "cache lookup failed for %s %u",
4179
4181 tuple,
4182 get_object_attnum_owner(classid)));
4183 ReleaseSysCache(tuple);
4184 }
4185 else
4186 {
4187 /* for catalogs without an appropriate syscache */
4188 Relation rel;
4189 ScanKeyData entry[1];
4190 SysScanDesc scan;
4191 HeapTuple tuple;
4192 bool isnull;
4193
4194 rel = table_open(classid, AccessShareLock);
4195
4196 ScanKeyInit(&entry[0],
4197 get_object_attnum_oid(classid),
4200
4201 scan = systable_beginscan(rel,
4202 get_object_oid_index(classid), true,
4203 NULL, 1, entry);
4204
4205 tuple = systable_getnext(scan);
4206 if (!HeapTupleIsValid(tuple))
4207 elog(ERROR, "could not find tuple for %s %u",
4209
4210 ownerId = DatumGetObjectId(heap_getattr(tuple,
4211 get_object_attnum_owner(classid),
4212 RelationGetDescr(rel),
4213 &isnull));
4214 Assert(!isnull);
4215
4216 systable_endscan(scan);
4218 }
4219
4220 return has_privs_of_role(roleid, ownerId);
4221}
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:917
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:133

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:3575
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:3516
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 3934 of file aclchk.c.

3936{
3938}
AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3946

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 3976 of file aclchk.c.

3978{
3980}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3987

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 3987 of file aclchk.c.

3990{
3994 Oid ownerId;
3995 AttrNumber nattrs;
3997
3998 /*
3999 * Must fetch pg_class row to get owner ID and number of attributes.
4000 */
4003 {
4004 if (is_missing != NULL)
4005 {
4006 /* return "no privileges" instead of throwing an error */
4007 *is_missing = true;
4008 return ACLCHECK_NO_PRIV;
4009 }
4010 else
4011 ereport(ERROR,
4013 errmsg("relation with OID %u does not exist",
4014 table_oid)));
4015 }
4017
4018 ownerId = classForm->relowner;
4019 nattrs = classForm->relnatts;
4020
4022
4023 /*
4024 * Initialize result in case there are no non-dropped columns. We want to
4025 * report failure in such cases for either value of 'how'.
4026 */
4028
4029 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4030 {
4033 bool isNull;
4034 Acl *acl;
4036
4040
4041 /*
4042 * Lookup failure probably indicates that the table was just dropped,
4043 * but we'll treat it the same as a dropped column rather than
4044 * throwing error.
4045 */
4047 continue;
4048
4049 /* ignore dropped columns */
4050 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4051 {
4053 continue;
4054 }
4055
4057 &isNull);
4058
4059 /*
4060 * Here we hard-wire knowledge that the default ACL for a column
4061 * grants no privileges, so that we can fall out quickly in the very
4062 * common case where attacl is null.
4063 */
4064 if (isNull)
4065 attmask = 0;
4066 else
4067 {
4068 /* detoast column's ACL if necessary */
4069 acl = DatumGetAclP(aclDatum);
4070
4071 attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4072
4073 /* if we have a detoasted copy, free it */
4074 if (acl != DatumGetPointer(aclDatum))
4075 pfree(acl);
4076 }
4077
4079
4080 if (attmask != 0)
4081 {
4083 if (how == ACLMASK_ANY)
4084 break; /* succeed on any success */
4085 }
4086 else
4087 {
4089 if (how == ACLMASK_ALL)
4090 break; /* fail on any failure */
4091 }
4092 }
4093
4094 return result;
4095}
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 3946 of file aclchk.c.

3948{
3950 ACLMASK_ANY, is_missing) != 0)
3951 return ACLCHECK_OK;
3952 else
3953 return ACLCHECK_NO_PRIV;
3954}
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 if (!superuser_arg(roleid))
3341 {
3343 {
3345 {
3346 /*
3347 * For conflict log tables, allow non-superusers to perform
3348 * DELETE and TRUNCATE for cleanup and maintenance, while
3349 * still restricting INSERT, UPDATE, and USAGE.
3350 */
3351 mask &= ~(ACL_INSERT | ACL_UPDATE | ACL_USAGE);
3352 }
3353 else if (IsSystemClass(table_oid, classForm) &&
3354 classForm->relkind != RELKIND_VIEW)
3355 {
3356 /*
3357 * Deny anyone permission to update a system catalog unless
3358 * pg_authid.rolsuper is set.
3359 *
3360 * As of 7.4 we have some updatable system views; those
3361 * shouldn't be protected in this way. Assume the view rules
3362 * can take care of themselves. ACL_USAGE is if we ever have
3363 * system sequences.
3364 */
3366 ACL_USAGE);
3367 }
3368 }
3369 }
3370 else
3371 {
3372 /* Superusers bypass all permission-checking. */
3373 ReleaseSysCache(tuple);
3374 return mask;
3375 }
3376
3377 /*
3378 * Normal case: get the relation's ACL from pg_class
3379 */
3380 ownerId = classForm->relowner;
3381
3383 &isNull);
3384 if (isNull)
3385 {
3386 /* No ACL, so build default ACL */
3387 switch (classForm->relkind)
3388 {
3389 case RELKIND_SEQUENCE:
3390 acl = acldefault(OBJECT_SEQUENCE, ownerId);
3391 break;
3392 default:
3393 acl = acldefault(OBJECT_TABLE, ownerId);
3394 break;
3395 }
3396 aclDatum = (Datum) 0;
3397 }
3398 else
3399 {
3400 /* detoast rel's ACL if necessary */
3401 acl = DatumGetAclP(aclDatum);
3402 }
3403
3404 result = aclmask(acl, roleid, ownerId, mask, how);
3405
3406 /* if we have a detoasted copy, free it */
3407 if (acl && acl != DatumGetPointer(aclDatum))
3408 pfree(acl);
3409
3410 ReleaseSysCache(tuple);
3411
3412 /*
3413 * Check if ACL_SELECT is being checked and, if so, and not set already as
3414 * part of the result, then check if the user is a member of the
3415 * pg_read_all_data role, which allows read access to all relations.
3416 */
3417 if (mask & ACL_SELECT && !(result & ACL_SELECT) &&
3419 result |= ACL_SELECT;
3420
3421 /*
3422 * Check if ACL_INSERT, ACL_UPDATE, or ACL_DELETE is being checked and, if
3423 * so, and not set already as part of the result, then check if the user
3424 * is a member of the pg_write_all_data role, which allows
3425 * INSERT/UPDATE/DELETE access to all relations (except system catalogs,
3426 * which requires superuser, see above).
3427 */
3428 if (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE) &&
3431 result |= (mask & (ACL_INSERT | ACL_UPDATE | ACL_DELETE));
3432
3433 /*
3434 * Check if ACL_MAINTAIN is being checked and, if so, and not already set
3435 * as part of the result, then check if the user is a member of the
3436 * pg_maintain role, which allows VACUUM, ANALYZE, CLUSTER, REPACK,
3437 * REFRESH MATERIALIZED VIEW, REINDEX, and LOCK TABLE on all relations.
3438 */
3439 if (mask & ACL_MAINTAIN &&
3440 !(result & ACL_MAINTAIN) &&
3443
3444 return result;
3445}
bool IsConflictLogTableClass(Form_pg_class reltuple)
Definition catalog.c:242
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, IsConflictLogTableClass(), 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 4142 of file aclchk.c.

4144{
4146 ACLMASK_ANY, snapshot) != 0)
4147 return ACLCHECK_OK;
4148 else
4149 return ACLCHECK_NO_PRIV;
4150}

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 3575 of file aclchk.c.

3578{
3581 ScanKeyData entry[1];
3582 SysScanDesc scan;
3583 HeapTuple tuple;
3585 bool isNull;
3586 Acl *acl;
3587 Oid ownerId;
3588
3589 /* Superusers bypass all permission checking. */
3590 if (superuser_arg(roleid))
3591 return mask;
3592
3593 /*
3594 * Get the largeobject's ACL from pg_largeobject_metadata
3595 */
3598
3599 ScanKeyInit(&entry[0],
3603
3606 snapshot, 1, entry);
3607
3608 tuple = systable_getnext(scan);
3609 if (!HeapTupleIsValid(tuple))
3610 ereport(ERROR,
3612 errmsg("large object %u does not exist", lobj_oid)));
3613
3614 ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner;
3615
3617 RelationGetDescr(pg_lo_meta), &isNull);
3618
3619 if (isNull)
3620 {
3621 /* No ACL, so build default ACL */
3622 acl = acldefault(OBJECT_LARGEOBJECT, ownerId);
3623 aclDatum = (Datum) 0;
3624 }
3625 else
3626 {
3627 /* detoast ACL if necessary */
3628 acl = DatumGetAclP(aclDatum);
3629 }
3630
3631 result = aclmask(acl, roleid, ownerId, mask, how);
3632
3633 /* if we have a detoasted copy, free it */
3634 if (acl && acl != DatumGetPointer(aclDatum))
3635 pfree(acl);
3636
3637 systable_endscan(scan);
3638
3640
3641 /*
3642 * Check if ACL_SELECT is being checked and, if so, and not set already as
3643 * part of the result, then check if the user has privileges of the
3644 * pg_read_all_data role, which allows read access to all large objects.
3645 */
3646 if (mask & ACL_SELECT && !(result & ACL_SELECT) &&
3648 result |= ACL_SELECT;
3649
3650 /*
3651 * Check if ACL_UPDATE is being checked and, if so, and not set already as
3652 * part of the result, then check if the user has privileges of the
3653 * pg_write_all_data role, which allows write access to all large objects.
3654 */
3655 if (mask & ACL_UPDATE && !(result & ACL_UPDATE) &&
3657 result |= ACL_UPDATE;
3658
3659 return result;
3660}

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 3666 of file aclchk.c.

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

References ACL_ALL_RIGHTS_SCHEMA, ACL_CREATE, 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, IsBinaryUpgrade, IsConflictLogTableNamespace(), 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 3516 of file aclchk.c.

3517{
3519 HeapTuple tuple;
3521 bool isNull;
3522 Acl *acl;
3523
3524 /* Superusers bypass all permission checking. */
3525 if (superuser_arg(roleid))
3526 return mask;
3527
3528 /* Get the ACL from pg_parameter_acl */
3530 if (!HeapTupleIsValid(tuple))
3531 ereport(ERROR,
3533 errmsg("parameter ACL with OID %u does not exist",
3534 acl_oid)));
3535
3538 &isNull);
3539 if (isNull)
3540 {
3541 /* No ACL, so build default ACL */
3543 aclDatum = (Datum) 0;
3544 }
3545 else
3546 {
3547 /* detoast ACL if necessary */
3548 acl = DatumGetAclP(aclDatum);
3549 }
3550
3551 result = aclmask(acl, roleid, BOOTSTRAP_SUPERUSERID, mask, how);
3552
3553 /* if we have a detoasted copy, free it */
3554 if (acl && acl != DatumGetPointer(aclDatum))
3555 pfree(acl);
3556
3557 ReleaseSysCache(tuple);
3558
3559 return result;
3560}

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 4130 of file aclchk.c.

4131{
4132 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4133 return ACLCHECK_OK;
4134 else
4135 return ACLCHECK_NO_PRIV;
4136}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3452
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 3452 of file aclchk.c.

3453{
3455 char *parname;
3456 text *partext;
3457 HeapTuple tuple;
3458
3459 /* Superusers bypass all permission checking. */
3460 if (superuser_arg(roleid))
3461 return mask;
3462
3463 /* Convert name to the form it should have in pg_parameter_acl... */
3466
3467 /* ... and look it up */
3469
3470 if (!HeapTupleIsValid(tuple))
3471 {
3472 /* If no entry, GUC has no permissions for non-superusers */
3474 }
3475 else
3476 {
3478 bool isNull;
3479 Acl *acl;
3480
3483 &isNull);
3484 if (isNull)
3485 {
3486 /* No ACL, so build default ACL */
3488 aclDatum = (Datum) 0;
3489 }
3490 else
3491 {
3492 /* detoast ACL if necessary */
3493 acl = DatumGetAclP(aclDatum);
3494 }
3495
3496 result = aclmask(acl, roleid, BOOTSTRAP_SUPERUSERID, mask, how);
3497
3498 /* if we have a detoasted copy, free it */
3499 if (acl && acl != DatumGetPointer(aclDatum))
3500 pfree(acl);
3501
3502 ReleaseSysCache(tuple);
3503 }
3504
3505 pfree(parname);
3506 pfree(partext);
3507
3508 return result;
3509}
char * convert_GUC_name_for_parameter_acl(const char *name)
Definition guc.c:1252
Definition c.h:835
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 3776 of file aclchk.c.

3778{
3780 HeapTuple tuple;
3783 bool isNull;
3784 Acl *acl;
3785 Oid ownerId;
3786
3787 /* Bypass permission checks for superusers */
3788 if (superuser_arg(roleid))
3789 return mask;
3790
3791 /*
3792 * Must get the type's tuple from pg_type
3793 */
3795 if (!HeapTupleIsValid(tuple))
3796 {
3797 if (is_missing != NULL)
3798 {
3799 /* return "no privileges" instead of throwing an error */
3800 *is_missing = true;
3801 return 0;
3802 }
3803 else
3804 ereport(ERROR,
3806 errmsg("type with OID %u does not exist",
3807 type_oid)));
3808 }
3809 typeForm = (Form_pg_type) GETSTRUCT(tuple);
3810
3811 /*
3812 * "True" array types don't manage permissions of their own; consult the
3813 * element type instead.
3814 */
3816 {
3817 Oid elttype_oid = typeForm->typelem;
3818
3819 ReleaseSysCache(tuple);
3820
3822 if (!HeapTupleIsValid(tuple))
3823 {
3824 if (is_missing != NULL)
3825 {
3826 /* return "no privileges" instead of throwing an error */
3827 *is_missing = true;
3828 return 0;
3829 }
3830 else
3831 ereport(ERROR,
3833 errmsg("type with OID %u does not exist",
3834 elttype_oid)));
3835 }
3836 typeForm = (Form_pg_type) GETSTRUCT(tuple);
3837 }
3838
3839 /*
3840 * Likewise, multirange types don't manage their own permissions; consult
3841 * the associated range type. (Note we must do this after the array step
3842 * to get the right answer for arrays of multiranges.)
3843 */
3844 if (typeForm->typtype == TYPTYPE_MULTIRANGE)
3845 {
3847
3848 ReleaseSysCache(tuple);
3849
3851 if (!HeapTupleIsValid(tuple))
3852 {
3853 if (is_missing != NULL)
3854 {
3855 /* return "no privileges" instead of throwing an error */
3856 *is_missing = true;
3857 return 0;
3858 }
3859 else
3860 ereport(ERROR,
3862 errmsg("type with OID %u does not exist",
3863 rangetype)));
3864 }
3865 typeForm = (Form_pg_type) GETSTRUCT(tuple);
3866 }
3867
3868 /*
3869 * Now get the type's owner and ACL from the tuple
3870 */
3871 ownerId = typeForm->typowner;
3872
3874 Anum_pg_type_typacl, &isNull);
3875 if (isNull)
3876 {
3877 /* No ACL, so build default ACL */
3878 acl = acldefault(OBJECT_TYPE, ownerId);
3879 aclDatum = (Datum) 0;
3880 }
3881 else
3882 {
3883 /* detoast rel's ACL if necessary */
3884 acl = DatumGetAclP(aclDatum);
3885 }
3886
3887 result = aclmask(acl, roleid, ownerId, mask, how);
3888
3889 /* if we have a detoasted copy, free it */
3890 if (acl && acl != DatumGetPointer(aclDatum))
3891 pfree(acl);
3892
3893 ReleaseSysCache(tuple);
3894
3895 return result;
3896}
Oid get_multirange_range(Oid multirangeOid)
Definition lsyscache.c:3844

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_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 4393 of file aclchk.c.

4395{
4396 int nmembers;
4397 Oid *members;
4398
4399 /* Nothing to do if ACL is defaulted */
4400 if (acl == NULL)
4401 return;
4402
4403 /* Extract roles mentioned in ACL */
4404 nmembers = aclmembers(acl, &members);
4405
4406 /* Update the shared dependency ACL info */
4407 updateAclDependencies(classId, objectId, objsubId,
4408 ownerId,
4409 0, NULL,
4410 nmembers, members);
4411}

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 4667 of file aclchk.c.

4668{
4669 /*
4670 * Generally, we only record the initial privileges when an extension is
4671 * being created, but because we don't actually use CREATE EXTENSION
4672 * during binary upgrades with pg_upgrade, there is a variable to let us
4673 * know that the GRANT and REVOKE statements being issued, while this
4674 * variable is true, are for the initial privileges of the extension
4675 * object and therefore we need to record them.
4676 */
4678 return;
4679
4680 recordExtensionInitPrivWorker(objoid, classoid, objsubid, new_acl);
4681}
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition aclchk.c:4696
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 4696 of file aclchk.c.

4698{
4699 Relation relation;
4700 ScanKeyData key[3];
4701 SysScanDesc scan;
4702 HeapTuple tuple;
4703 HeapTuple oldtuple;
4704 int noldmembers;
4705 int nnewmembers;
4706 Oid *oldmembers;
4707 Oid *newmembers;
4708
4709 /* We'll need the role membership of the new ACL. */
4711
4712 /* Search pg_init_privs for an existing entry. */
4714
4715 ScanKeyInit(&key[0],
4718 ObjectIdGetDatum(objoid));
4719 ScanKeyInit(&key[1],
4722 ObjectIdGetDatum(classoid));
4723 ScanKeyInit(&key[2],
4726 Int32GetDatum(objsubid));
4727
4728 scan = systable_beginscan(relation, InitPrivsObjIndexId, true,
4729 NULL, 3, key);
4730
4731 /* There should exist only one entry or none. */
4732 oldtuple = systable_getnext(scan);
4733
4734 /* If we find an entry, update it with the latest ACL. */
4735 if (HeapTupleIsValid(oldtuple))
4736 {
4738 bool nulls[Natts_pg_init_privs] = {0};
4739 bool replace[Natts_pg_init_privs] = {0};
4741 bool isNull;
4742 Acl *old_acl;
4743
4744 /* Update pg_shdepend for roles mentioned in the old/new ACLs. */
4746 RelationGetDescr(relation), &isNull);
4747 Assert(!isNull);
4750
4751 updateInitAclDependencies(classoid, objoid, objsubid,
4754
4755 /* If we have a new ACL to set, then update the row with it. */
4756 if (new_acl && ACL_NUM(new_acl) != 0)
4757 {
4759 replace[Anum_pg_init_privs_initprivs - 1] = true;
4760
4761 oldtuple = heap_modify_tuple(oldtuple, RelationGetDescr(relation),
4762 values, nulls, replace);
4763
4764 CatalogTupleUpdate(relation, &oldtuple->t_self, oldtuple);
4765 }
4766 else
4767 {
4768 /* new_acl is NULL/empty, so delete the entry we found. */
4769 CatalogTupleDelete(relation, &oldtuple->t_self);
4770 }
4771 }
4772 else
4773 {
4775 bool nulls[Natts_pg_init_privs] = {0};
4776
4777 /*
4778 * Only add a new entry if the new ACL is non-NULL.
4779 *
4780 * If we are passed in a NULL ACL and no entry exists, we can just
4781 * fall through and do nothing.
4782 */
4783 if (new_acl && ACL_NUM(new_acl) != 0)
4784 {
4785 /* No entry found, so add it. */
4789
4790 /* This function only handles initial privileges of extensions */
4793
4795
4796 tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
4797
4798 CatalogTupleInsert(relation, tuple);
4799
4800 /* Update pg_shdepend, too. */
4801 noldmembers = 0;
4802 oldmembers = NULL;
4803
4804 updateInitAclDependencies(classoid, objoid, objsubid,
4807 }
4808 }
4809
4810 systable_endscan(scan);
4811
4812 /* prevent error when processing objects multiple times */
4814
4815 table_close(relation, RowExclusiveLock);
4816}
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 4420 of file aclchk.c.

4421{
4422 /*
4423 * pg_class / pg_attribute
4424 *
4425 * If this is a relation then we need to see if there are any sub-objects
4426 * (eg: columns) for it and, if so, be sure to call
4427 * recordExtensionInitPrivWorker() for each one.
4428 */
4429 if (classoid == RelationRelationId)
4430 {
4433 bool isNull;
4434 HeapTuple tuple;
4435
4436 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4437 if (!HeapTupleIsValid(tuple))
4438 elog(ERROR, "cache lookup failed for relation %u", objoid);
4440
4441 /*
4442 * Indexes don't have permissions, neither do the pg_class rows for
4443 * composite types. (These cases are unreachable given the
4444 * restrictions in ALTER EXTENSION ADD, but let's check anyway.)
4445 */
4446 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4449 {
4450 ReleaseSysCache(tuple);
4451 return;
4452 }
4453
4454 /*
4455 * If this isn't a sequence then it's possibly going to have
4456 * column-level ACLs associated with it.
4457 */
4458 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4459 {
4461 AttrNumber nattrs = pg_class_tuple->relnatts;
4462
4463 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4464 {
4467
4469 ObjectIdGetDatum(objoid),
4471
4473 continue;
4474
4475 /* ignore dropped columns */
4476 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4477 {
4479 continue;
4480 }
4481
4484 &isNull);
4485
4486 /* no need to do anything for a NULL ACL */
4487 if (isNull)
4488 {
4490 continue;
4491 }
4492
4493 recordExtensionInitPrivWorker(objoid, classoid, curr_att,
4495
4497 }
4498 }
4499
4501 &isNull);
4502
4503 /* Add the record, if any, for the top-level object */
4504 if (!isNull)
4505 recordExtensionInitPrivWorker(objoid, classoid, 0,
4507
4508 ReleaseSysCache(tuple);
4509 }
4510 else if (classoid == LargeObjectRelationId)
4511 {
4512 /* For large objects, we must consult pg_largeobject_metadata */
4514 bool isNull;
4515 HeapTuple tuple;
4516 ScanKeyData entry[1];
4517 SysScanDesc scan;
4518 Relation relation;
4519
4520 /*
4521 * Note: this is dead code, given that we don't allow large objects to
4522 * be made extension members. But it seems worth carrying in case
4523 * some future caller of this function has need for it.
4524 */
4526
4527 /* There's no syscache for pg_largeobject_metadata */
4528 ScanKeyInit(&entry[0],
4531 ObjectIdGetDatum(objoid));
4532
4533 scan = systable_beginscan(relation,
4535 NULL, 1, entry);
4536
4537 tuple = systable_getnext(scan);
4538 if (!HeapTupleIsValid(tuple))
4539 elog(ERROR, "could not find tuple for large object %u", objoid);
4540
4541 aclDatum = heap_getattr(tuple,
4543 RelationGetDescr(relation), &isNull);
4544
4545 /* Add the record, if any, for the top-level object */
4546 if (!isNull)
4547 recordExtensionInitPrivWorker(objoid, classoid, 0,
4549
4550 systable_endscan(scan);
4551 }
4552 /* This will error on unsupported classoid. */
4553 else if (get_object_attnum_acl(classoid) != InvalidAttrNumber)
4554 {
4557 bool isNull;
4558 HeapTuple tuple;
4559
4560 cacheid = get_object_catcache_oid(classoid);
4561 tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objoid));
4562 if (!HeapTupleIsValid(tuple))
4563 elog(ERROR, "cache lookup failed for %s %u",
4564 get_object_class_descr(classoid), objoid);
4565
4567 get_object_attnum_acl(classoid),
4568 &isNull);
4569
4570 /* Add the record, if any, for the top-level object */
4571 if (!isNull)
4572 recordExtensionInitPrivWorker(objoid, classoid, 0,
4574
4575 ReleaseSysCache(tuple);
4576 }
4577}

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 4584 of file aclchk.c.

4585{
4586 /*
4587 * If this is a relation then we need to see if there are any sub-objects
4588 * (eg: columns) for it and, if so, be sure to call
4589 * recordExtensionInitPrivWorker() for each one.
4590 */
4591 if (classoid == RelationRelationId)
4592 {
4594 HeapTuple tuple;
4595
4596 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(objoid));
4597 if (!HeapTupleIsValid(tuple))
4598 elog(ERROR, "cache lookup failed for relation %u", objoid);
4600
4601 /*
4602 * Indexes don't have permissions, neither do the pg_class rows for
4603 * composite types. (These cases are unreachable given the
4604 * restrictions in ALTER EXTENSION DROP, but let's check anyway.)
4605 */
4606 if (pg_class_tuple->relkind == RELKIND_INDEX ||
4609 {
4610 ReleaseSysCache(tuple);
4611 return;
4612 }
4613
4614 /*
4615 * If this isn't a sequence then it's possibly going to have
4616 * column-level ACLs associated with it.
4617 */
4618 if (pg_class_tuple->relkind != RELKIND_SEQUENCE)
4619 {
4621 AttrNumber nattrs = pg_class_tuple->relnatts;
4622
4623 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4624 {
4626
4628 ObjectIdGetDatum(objoid),
4630
4632 continue;
4633
4634 /* when removing, remove all entries, even dropped columns */
4635
4636 recordExtensionInitPrivWorker(objoid, classoid, curr_att, NULL);
4637
4639 }
4640 }
4641
4642 ReleaseSysCache(tuple);
4643 }
4644
4645 /* Remove the record, if any, for the top-level object */
4646 recordExtensionInitPrivWorker(objoid, classoid, 0, NULL);
4647}

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 4933 of file aclchk.c.

4934{
4935 Relation rel;
4936 ScanKeyData key[3];
4937 SysScanDesc scan;
4938 HeapTuple oldtuple;
4941 Oid ownerId;
4943 bool isNull;
4944 Acl *old_acl;
4945 Acl *new_acl;
4946 HeapTuple newtuple;
4947 int noldmembers;
4948 int nnewmembers;
4949 Oid *oldmembers;
4950 Oid *newmembers;
4951
4952 /* Search for existing pg_init_privs entry for the target object. */
4954
4955 ScanKeyInit(&key[0],
4958 ObjectIdGetDatum(objid));
4959 ScanKeyInit(&key[1],
4962 ObjectIdGetDatum(classid));
4963 ScanKeyInit(&key[2],
4966 Int32GetDatum(objsubid));
4967
4968 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4969 NULL, 3, key);
4970
4971 /* There should exist only one entry or none. */
4972 oldtuple = systable_getnext(scan);
4973
4974 if (!HeapTupleIsValid(oldtuple))
4975 {
4976 /*
4977 * Hmm, why are we here if there's no entry? But pack up and go away
4978 * quietly.
4979 */
4980 systable_endscan(scan);
4982 return;
4983 }
4984
4985 /* Get a writable copy of the existing ACL. */
4987 RelationGetDescr(rel), &isNull);
4988 Assert(!isNull);
4990
4991 /*
4992 * We need the members of both old and new ACLs so we can correct the
4993 * shared dependency information. Collect data before
4994 * merge_acl_with_grant throws away old_acl.
4995 */
4997
4998 /* Must find out the owner's OID the hard way. */
5002 elog(ERROR, "cache lookup failed for %s %u",
5003 get_object_class_descr(classid), objid);
5004
5006 objtuple,
5007 get_object_attnum_owner(classid)));
5009
5010 /*
5011 * Generate new ACL. Grantor of rights is always the same as the owner.
5012 */
5013 if (old_acl != NULL)
5015 false, /* is_grant */
5016 false, /* grant_option */
5018 list_make1_oid(roleid),
5020 ownerId,
5021 ownerId);
5022 else
5023 new_acl = NULL; /* this case shouldn't happen, probably */
5024
5025 /* If we end with an empty ACL, delete the pg_init_privs entry. */
5026 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
5027 {
5028 CatalogTupleDelete(rel, &oldtuple->t_self);
5029 }
5030 else
5031 {
5033 bool nulls[Natts_pg_init_privs] = {0};
5034 bool replaces[Natts_pg_init_privs] = {0};
5035
5036 /* Update existing entry. */
5039
5040 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
5041 values, nulls, replaces);
5042 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
5043 }
5044
5045 /*
5046 * Update the shared dependency ACL info.
5047 */
5049
5050 updateInitAclDependencies(classid, objid, objsubid,
5053
5054 systable_endscan(scan);
5055
5056 /* prevent error when processing objects multiple times */
5058
5060}
#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 4824 of file aclchk.c.

4826{
4827 Relation rel;
4828 ScanKeyData key[3];
4829 SysScanDesc scan;
4830 HeapTuple oldtuple;
4832 bool isNull;
4833 Acl *old_acl;
4834 Acl *new_acl;
4835 HeapTuple newtuple;
4836 int noldmembers;
4837 int nnewmembers;
4838 Oid *oldmembers;
4839 Oid *newmembers;
4840
4841 /* Search for existing pg_init_privs entry for the target object. */
4843
4844 ScanKeyInit(&key[0],
4847 ObjectIdGetDatum(objid));
4848 ScanKeyInit(&key[1],
4851 ObjectIdGetDatum(classid));
4852 ScanKeyInit(&key[2],
4855 Int32GetDatum(objsubid));
4856
4857 scan = systable_beginscan(rel, InitPrivsObjIndexId, true,
4858 NULL, 3, key);
4859
4860 /* There should exist only one entry or none. */
4861 oldtuple = systable_getnext(scan);
4862
4863 if (!HeapTupleIsValid(oldtuple))
4864 {
4865 /*
4866 * Hmm, why are we here if there's no entry? But pack up and go away
4867 * quietly.
4868 */
4869 systable_endscan(scan);
4871 return;
4872 }
4873
4874 /* Get a writable copy of the existing ACL. */
4876 RelationGetDescr(rel), &isNull);
4877 Assert(!isNull);
4879
4880 /*
4881 * Generate new ACL. This usage of aclnewowner is a bit off-label when
4882 * oldroleid isn't the owner; but it does the job fine.
4883 */
4885
4886 /*
4887 * If we end with an empty ACL, delete the pg_init_privs entry. (That
4888 * probably can't happen here, but we may as well cover the case.)
4889 */
4890 if (new_acl == NULL || ACL_NUM(new_acl) == 0)
4891 {
4892 CatalogTupleDelete(rel, &oldtuple->t_self);
4893 }
4894 else
4895 {
4897 bool nulls[Natts_pg_init_privs] = {0};
4898 bool replaces[Natts_pg_init_privs] = {0};
4899
4900 /* Update existing entry. */
4903
4904 newtuple = heap_modify_tuple(oldtuple, RelationGetDescr(rel),
4905 values, nulls, replaces);
4906 CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
4907 }
4908
4909 /*
4910 * Update the shared dependency ACL info.
4911 */
4914
4915 updateInitAclDependencies(classid, objid, objsubid,
4918
4919 systable_endscan(scan);
4920
4921 /* prevent error when processing objects multiple times */
4923
4925}
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
Definition acl.c:1150

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:475
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:51
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().