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

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

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

Referenced by aclcheck_error_col(), aclcheck_error_type(), AlterCollation(), AlterDatabase(), AlterDatabaseOwner(), AlterDatabaseRefreshColl(), AlterDatabaseSet(), AlterEventTrigger(), AlterEventTriggerOwner_internal(), AlterExtensionNamespace(), AlterForeignServer(), AlterForeignServerOwner_internal(), AlterFunction(), AlterObjectNamespace_internal(), AlterObjectOwner_internal(), AlterObjectRename_internal(), AlterOperator(), AlterOpFamilyAdd(), AlterPublication(), AlterPublicationOwner_internal(), AlterRoleSet(), AlterSchemaOwner_internal(), AlterStatistics(), AlterSubscription(), AlterSubscriptionOwner_internal(), AlterTableMoveAll(), AlterTableSpaceOptions(), AlterTSConfiguration(), AlterTSDictionary(), AlterTypeOwner(), ATExecChangeOwner(), ATPrepSetTableSpace(), ATSimplePermissions(), brin_desummarize_range(), brin_summarize_range(), calculate_database_size(), calculate_tablespace_size(), call_pltcl_start_proc(), check_object_ownership(), check_temp_tablespaces(), checkFkeyPermissions(), CheckFunctionValidatorAccess(), compute_return_type(), CreateConversionCommand(), createdb(), CreateForeignServer(), CreateForeignTable(), CreateFunction(), CreateProceduralLanguage(), CreatePublication(), CreateSchemaCommand(), CreateStatistics(), CreateSubscription(), CreateTransform(), CreateTriggerFiringOn(), currtid_internal(), DefineAggregate(), DefineCollation(), DefineDomain(), DefineEnum(), DefineIndex(), DefineOpClass(), DefineOperator(), DefineOpFamily(), DefineQueryRewrite(), DefineRange(), DefineRelation(), DefineTSConfiguration(), DefineTSDictionary(), DefineType(), dropdb(), DropSubscription(), DropTableSpace(), EnableDisableRule(), ExecAlterExtensionContentsStmt(), ExecAlterExtensionStmt(), ExecBuildGroupingEqual(), ExecBuildParamSetEqual(), ExecCheckPermissions(), ExecInitAgg(), ExecInitExprRec(), ExecInitFunc(), ExecInitWindowAgg(), ExecReindex(), ExecuteCallStmt(), ExecuteDoStmt(), ExecuteTruncateGuts(), findRangeCanonicalFunction(), findRangeSubtypeDiffFunction(), get_connect_string(), get_other_operator(), gin_clean_pending_list(), HandleFunctionRequest(), heap_force_common(), ImportForeignSchema(), init_sexpr(), initialize_peragg(), LockViewRecurse_walker(), LogicalRepSyncTableStart(), lookup_agg_function(), LookupCreationNamespace(), LookupExplicitNamespace(), MergeAttributes(), movedb(), OperatorCreate(), pg_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(), 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 2978 of file aclchk.c.

2980{
2981 switch (aclerr)
2982 {
2983 case ACLCHECK_OK:
2984 /* no error, so return to caller */
2985 break;
2986 case ACLCHECK_NO_PRIV:
2987 ereport(ERROR,
2989 errmsg("permission denied for column \"%s\" of relation \"%s\"",
2990 colname, objectname)));
2991 break;
2992 case ACLCHECK_NOT_OWNER:
2993 /* relation msg is OK since columns don't have separate owners */
2994 aclcheck_error(aclerr, objtype, objectname);
2995 break;
2996 default:
2997 elog(ERROR, "unrecognized AclResult: %d", (int) aclerr);
2998 break;
2999 }
3000}
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2683

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

930{
931 GrantStmt *action = stmt->action;
933 ListCell *cell;
934 List *rolespecs = NIL;
935 List *nspnames = NIL;
939 const char *errormsg;
940
941 /* Deconstruct the "options" part of the statement */
942 foreach(cell, stmt->options)
943 {
944 DefElem *defel = (DefElem *) lfirst(cell);
945
946 if (strcmp(defel->defname, "schemas") == 0)
947 {
948 if (dnspnames)
951 }
952 else if (strcmp(defel->defname, "roles") == 0)
953 {
954 if (drolespecs)
957 }
958 else
959 elog(ERROR, "option \"%s\" not recognized", defel->defname);
960 }
961
962 if (dnspnames)
963 nspnames = (List *) dnspnames->arg;
964 if (drolespecs)
965 rolespecs = (List *) drolespecs->arg;
966
967 /* Prepare the InternalDefaultACL representation of the statement */
968 /* roleid to be filled below */
969 /* nspid to be filled in SetDefaultACLsInSchemas */
970 iacls.is_grant = action->is_grant;
971 iacls.objtype = action->objtype;
972 /* all_privs to be filled below */
973 /* privileges to be filled below */
974 iacls.grantees = NIL; /* filled below */
975 iacls.grant_option = action->grant_option;
976 iacls.behavior = action->behavior;
977
978 /*
979 * Convert the RoleSpec list into an Oid list. Note that at this point we
980 * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
981 * there shouldn't be any additional work needed to support this case.
982 */
983 foreach(cell, action->grantees)
984 {
985 RoleSpec *grantee = (RoleSpec *) lfirst(cell);
987
988 switch (grantee->roletype)
989 {
990 case ROLESPEC_PUBLIC:
992 break;
993 default:
995 break;
996 }
997 iacls.grantees = lappend_oid(iacls.grantees, grantee_uid);
998 }
999
1000 /*
1001 * Convert action->privileges, a list of privilege strings, into an
1002 * AclMode bitmask.
1003 */
1004 switch (action->objtype)
1005 {
1006 case OBJECT_TABLE:
1008 errormsg = gettext_noop("invalid privilege type %s for relation");
1009 break;
1010 case OBJECT_SEQUENCE:
1012 errormsg = gettext_noop("invalid privilege type %s for sequence");
1013 break;
1014 case OBJECT_FUNCTION:
1016 errormsg = gettext_noop("invalid privilege type %s for function");
1017 break;
1018 case OBJECT_PROCEDURE:
1020 errormsg = gettext_noop("invalid privilege type %s for procedure");
1021 break;
1022 case OBJECT_ROUTINE:
1024 errormsg = gettext_noop("invalid privilege type %s for routine");
1025 break;
1026 case OBJECT_TYPE:
1028 errormsg = gettext_noop("invalid privilege type %s for type");
1029 break;
1030 case OBJECT_SCHEMA:
1032 errormsg = gettext_noop("invalid privilege type %s for schema");
1033 break;
1034 case OBJECT_LARGEOBJECT:
1036 errormsg = gettext_noop("invalid privilege type %s for large object");
1037 break;
1038 case OBJECT_PROPGRAPH:
1040 errormsg = gettext_noop("invalid privilege type %s for property graph");
1041 break;
1042 default:
1043 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
1044 (int) action->objtype);
1045 /* keep compiler quiet */
1047 errormsg = NULL;
1048 }
1049
1050 if (action->privileges == NIL)
1051 {
1052 iacls.all_privs = true;
1053
1054 /*
1055 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
1056 * depending on the object type
1057 */
1058 iacls.privileges = ACL_NO_RIGHTS;
1059 }
1060 else
1061 {
1062 iacls.all_privs = false;
1063 iacls.privileges = ACL_NO_RIGHTS;
1064
1065 foreach(cell, action->privileges)
1066 {
1067 AccessPriv *privnode = (AccessPriv *) lfirst(cell);
1068 AclMode priv;
1069
1070 if (privnode->cols)
1071 ereport(ERROR,
1073 errmsg("default privileges cannot be set for columns")));
1074
1075 if (privnode->priv_name == NULL) /* parser mistake? */
1076 elog(ERROR, "AccessPriv node must specify privilege");
1077 priv = string_to_privilege(privnode->priv_name);
1078
1079 if (priv & ~all_privileges)
1080 ereport(ERROR,
1082 errmsg(errormsg, privilege_to_string(priv))));
1083
1084 iacls.privileges |= priv;
1085 }
1086 }
1087
1088 if (rolespecs == NIL)
1089 {
1090 /* Set permissions for myself */
1091 iacls.roleid = GetUserId();
1092
1094 }
1095 else
1096 {
1097 /* Look up the role OIDs and do permissions checks */
1099
1100 foreach(rolecell, rolespecs)
1101 {
1103
1104 iacls.roleid = get_rolespec_oid(rolespec, false);
1105
1106 if (!has_privs_of_role(GetUserId(), iacls.roleid))
1107 ereport(ERROR,
1109 errmsg("permission denied to change default privileges")));
1110
1112 }
1113 }
1114}
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Definition acl.c:5616
#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:2595
static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames)
Definition aclchk.c:1122
static const char * privilege_to_string(AclMode privilege)
Definition aclchk.c:2636
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:423
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 1656 of file aclchk.c.

1659{
1662 Acl *old_acl;
1663 Acl *new_acl;
1664 Acl *merged_acl;
1666 bool isNull;
1667 Oid grantorId;
1669 bool need_update;
1670 HeapTuple newtuple;
1672 bool nulls[Natts_pg_attribute] = {0};
1673 bool replaces[Natts_pg_attribute] = {0};
1674 int noldmembers;
1675 int nnewmembers;
1676 Oid *oldmembers;
1677 Oid *newmembers;
1678
1680 ObjectIdGetDatum(relOid),
1683 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1684 attnum, relOid);
1686
1687 /*
1688 * Get working copy of existing ACL. If there's no ACL, substitute the
1689 * proper default.
1690 */
1692 &isNull);
1693 if (isNull)
1694 {
1695 old_acl = acldefault(OBJECT_COLUMN, ownerId);
1696 /* There are no old member roles according to the catalogs */
1697 noldmembers = 0;
1698 oldmembers = NULL;
1699 }
1700 else
1701 {
1703 /* Get the roles mentioned in the existing ACL */
1705 }
1706
1707 /*
1708 * In select_best_grantor we should consider existing table-level ACL bits
1709 * as well as the per-column ACL. Build a new ACL that is their
1710 * concatenation. (This is a bit cheap and dirty compared to merging them
1711 * properly with no duplications, but it's all we need here.)
1712 */
1714
1715 /* Determine ID to do the grant as, and available grant options */
1717 merged_acl, ownerId,
1719
1721
1722 /*
1723 * Restrict the privileges to what we can actually grant, and emit the
1724 * standards-mandated warning and error messages. Note: we don't track
1725 * whether the user actually used the ALL PRIVILEGES(columns) syntax for
1726 * each column; we just approximate it by whether all the possible
1727 * privileges are specified now. Since the all_privs flag only determines
1728 * whether a warning is issued, this seems close enough.
1729 */
1734 relOid, grantorId, OBJECT_COLUMN,
1735 relname, attnum,
1736 NameStr(pg_attribute_tuple->attname));
1737
1738 /*
1739 * Generate new ACL.
1740 */
1742 istmt->grant_option,
1743 istmt->behavior, istmt->grantees,
1745 ownerId);
1746
1747 /*
1748 * We need the members of both old and new ACLs so we can correct the
1749 * shared dependency information.
1750 */
1752
1753 /* finished building new ACL value, now insert it */
1754
1755 /*
1756 * If the updated ACL is empty, we can set attacl to null, and maybe even
1757 * avoid an update of the pg_attribute row. This is worth testing because
1758 * we'll come through here multiple times for any relation-level REVOKE,
1759 * even if there were never any column GRANTs. Note we are assuming that
1760 * the "default" ACL state for columns is empty.
1761 */
1762 if (ACL_NUM(new_acl) > 0)
1763 {
1765 need_update = true;
1766 }
1767 else
1768 {
1769 nulls[Anum_pg_attribute_attacl - 1] = true;
1770 need_update = !isNull;
1771 }
1773
1774 if (need_update)
1775 {
1777 values, nulls, replaces);
1778
1779 CatalogTupleUpdate(attRelation, &newtuple->t_self, newtuple);
1780
1781 /* Update initial privileges for extensions */
1783 ACL_NUM(new_acl) > 0 ? new_acl : NULL);
1784
1785 /* Update the shared dependency ACL info */
1787 ownerId,
1790 }
1791
1792 pfree(new_acl);
1793
1795}
Acl * aclconcat(const Acl *left_acl, const Acl *right_acl)
Definition acl.c:491
Acl * acldefault(ObjectType objtype, Oid ownerId)
Definition acl.c:827
void select_best_grantor(Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
Definition acl.c:5506
int aclmembers(const Acl *acl, Oid **roleids)
Definition acl.c:1568
#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:4655
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:181
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:240
static Datum values[MAXATTR]
Definition bootstrap.c:188
#define NameStr(name)
Definition c.h:837
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1130
#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:1616
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 PointerGetDatum(const void *X)
Definition postgres.h:342
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 RelationGetDescr(relation)
Definition rel.h:540
ItemPointerData t_self
Definition htup.h:65
DropBehavior behavior
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache2(SysCacheIdentifier cacheId, Datum key1, Datum key2)
Definition syscache.c:230
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595

References ACL_ALL_RIGHTS_COLUMN, ACL_NUM, aclconcat(), acldefault(), aclmembers(), attnum, InternalGrant::behavior, CatalogTupleUpdate(), DatumGetAclPCopy, elog, ERROR, fb(), GETSTRUCT(), GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, 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 2144 of file aclchk.c.

2146{
2148 Relation relation;
2149 ListCell *cell;
2150
2151 if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
2152 istmt->privileges = default_privs;
2153
2155
2156 relation = table_open(classid, RowExclusiveLock);
2157
2158 foreach(cell, istmt->objects)
2159 {
2160 Oid objectid = lfirst_oid(cell);
2163 bool isNull;
2166 Acl *old_acl;
2167 Acl *new_acl;
2168 Oid grantorId;
2169 Oid ownerId;
2170 HeapTuple tuple;
2171 HeapTuple newtuple;
2172 Datum *values = palloc0_array(Datum, RelationGetDescr(relation)->natts);
2173 bool *nulls = palloc0_array(bool, RelationGetDescr(relation)->natts);
2174 bool *replaces = palloc0_array(bool, RelationGetDescr(relation)->natts);
2175 int noldmembers;
2176 int nnewmembers;
2177 Oid *oldmembers;
2178 Oid *newmembers;
2179
2181 if (!HeapTupleIsValid(tuple))
2182 elog(ERROR, "cache lookup failed for %s %u", get_object_class_descr(classid), objectid);
2183
2184 /*
2185 * Additional object-type-specific checks
2186 */
2187 if (object_check)
2188 object_check(istmt, tuple);
2189
2190 /*
2191 * Get owner ID and working copy of existing ACL. If there's no ACL,
2192 * substitute the proper default.
2193 */
2195 tuple,
2196 get_object_attnum_owner(classid)));
2198 tuple,
2199 get_object_attnum_acl(classid),
2200 &isNull);
2201 if (isNull)
2202 {
2203 old_acl = acldefault(get_object_type(classid, objectid), ownerId);
2204 /* There are no old member roles according to the catalogs */
2205 noldmembers = 0;
2206 oldmembers = NULL;
2207 }
2208 else
2209 {
2211 /* Get the roles mentioned in the existing ACL */
2213 }
2214
2215 /* Determine ID to do the grant as, and available grant options */
2217 old_acl, ownerId,
2219
2221 get_object_attnum_name(classid));
2222
2223 /*
2224 * Restrict the privileges to what we can actually grant, and emit the
2225 * standards-mandated warning and error messages.
2226 */
2229 istmt->all_privs, istmt->privileges,
2232 0, NULL);
2233
2234 /*
2235 * Generate new ACL.
2236 */
2238 istmt->grant_option, istmt->behavior,
2239 istmt->grantees, this_privileges,
2240 grantorId, ownerId);
2241
2242 /*
2243 * We need the members of both old and new ACLs so we can correct the
2244 * shared dependency information.
2245 */
2247
2248 /* finished building new ACL value, now insert it */
2249 replaces[get_object_attnum_acl(classid) - 1] = true;
2251
2252 newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values,
2253 nulls, replaces);
2254
2255 CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
2256 UnlockTuple(relation, &tuple->t_self, InplaceUpdateTupleLock);
2257
2258 /* Update initial privileges for extensions */
2260
2261 /* Update the shared dependency ACL info */
2262 updateAclDependencies(classid,
2263 objectid, 0,
2264 ownerId,
2267
2268 ReleaseSysCache(tuple);
2269
2270 pfree(new_acl);
2271
2272 /* prevent error when processing duplicate objects */
2274 }
2275
2276 table_close(relation, RowExclusiveLock);
2277}
#define palloc0_array(type, count)
Definition fe_memutils.h:77
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:380
static Oid DatumGetObjectId(Datum X)
Definition postgres.h:242
HeapTuple SearchSysCacheLocked1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:282
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625
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:1102

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(), GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, 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 2280 of file aclchk.c.

2281{
2283
2285
2286 if (!pg_language_tuple->lanpltrusted)
2287 ereport(ERROR,
2289 errmsg("language \"%s\" is not trusted",
2290 NameStr(pg_language_tuple->lanname)),
2291 errdetail("GRANT and REVOKE are not allowed on untrusted languages, "
2292 "because only superusers can use untrusted languages.")));
2293}
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 2296 of file aclchk.c.

2297{
2298 Relation relation;
2299 ListCell *cell;
2300
2301 if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
2303
2306
2307 foreach(cell, istmt->objects)
2308 {
2309 Oid loid = lfirst_oid(cell);
2311 char loname[NAMEDATALEN];
2313 bool isNull;
2316 Acl *old_acl;
2317 Acl *new_acl;
2318 Oid grantorId;
2319 Oid ownerId;
2320 HeapTuple newtuple;
2322 bool nulls[Natts_pg_largeobject_metadata] = {0};
2324 int noldmembers;
2325 int nnewmembers;
2326 Oid *oldmembers;
2327 Oid *newmembers;
2328 ScanKeyData entry[1];
2329 SysScanDesc scan;
2330 HeapTuple tuple;
2331
2332 /* There's no syscache for pg_largeobject_metadata */
2333 ScanKeyInit(&entry[0],
2337
2338 scan = systable_beginscan(relation,
2340 NULL, 1, entry);
2341
2342 tuple = systable_getnext(scan);
2343 if (!HeapTupleIsValid(tuple))
2344 elog(ERROR, "could not find tuple for large object %u", loid);
2345
2347
2348 /*
2349 * Get owner ID and working copy of existing ACL. If there's no ACL,
2350 * substitute the proper default.
2351 */
2352 ownerId = form_lo_meta->lomowner;
2353 aclDatum = heap_getattr(tuple,
2355 RelationGetDescr(relation), &isNull);
2356 if (isNull)
2357 {
2359 /* There are no old member roles according to the catalogs */
2360 noldmembers = 0;
2361 oldmembers = NULL;
2362 }
2363 else
2364 {
2366 /* Get the roles mentioned in the existing ACL */
2368 }
2369
2370 /* Determine ID to do the grant as, and available grant options */
2372 old_acl, ownerId,
2374
2375 /*
2376 * Restrict the privileges to what we can actually grant, and emit the
2377 * standards-mandated warning and error messages.
2378 */
2379 snprintf(loname, sizeof(loname), "large object %u", loid);
2382 istmt->all_privs, istmt->privileges,
2384 loname, 0, NULL);
2385
2386 /*
2387 * Generate new ACL.
2388 */
2390 istmt->grant_option, istmt->behavior,
2391 istmt->grantees, this_privileges,
2392 grantorId, ownerId);
2393
2394 /*
2395 * We need the members of both old and new ACLs so we can correct the
2396 * shared dependency information.
2397 */
2399
2400 /* finished building new ACL value, now insert it */
2404
2405 newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation),
2406 values, nulls, replaces);
2407
2408 CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
2409
2410 /* Update initial privileges for extensions */
2412
2413 /* Update the shared dependency ACL info */
2415 form_lo_meta->oid, 0,
2416 ownerId,
2419
2420 systable_endscan(scan);
2421
2422 pfree(new_acl);
2423
2424 /* prevent error when processing duplicate objects */
2426 }
2427
2428 table_close(relation, RowExclusiveLock);
2429}
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
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:260
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(), GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, 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 2452 of file aclchk.c.

2453{
2454 Relation relation;
2455 ListCell *cell;
2456
2457 if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
2459
2461
2462 foreach(cell, istmt->objects)
2463 {
2464 Oid parameterId = lfirst_oid(cell);
2466 const char *parname;
2468 bool isNull;
2471 Acl *old_acl;
2472 Acl *new_acl;
2473 Oid grantorId;
2474 Oid ownerId;
2475 HeapTuple tuple;
2476 int noldmembers;
2477 int nnewmembers;
2478 Oid *oldmembers;
2479 Oid *newmembers;
2480
2482 if (!HeapTupleIsValid(tuple))
2483 elog(ERROR, "cache lookup failed for parameter ACL %u",
2484 parameterId);
2485
2486 /* We'll need the GUC's name */
2490
2491 /* Treat all parameters as belonging to the bootstrap superuser. */
2492 ownerId = BOOTSTRAP_SUPERUSERID;
2493
2494 /*
2495 * Get working copy of existing ACL. If there's no ACL, substitute the
2496 * proper default.
2497 */
2500 &isNull);
2501
2502 if (isNull)
2503 {
2504 old_acl = acldefault(istmt->objtype, ownerId);
2505 /* There are no old member roles according to the catalogs */
2506 noldmembers = 0;
2507 oldmembers = NULL;
2508 }
2509 else
2510 {
2512 /* Get the roles mentioned in the existing ACL */
2514 }
2515
2516 /* Determine ID to do the grant as, and available grant options */
2518 old_acl, ownerId,
2520
2521 /*
2522 * Restrict the privileges to what we can actually grant, and emit the
2523 * standards-mandated warning and error messages.
2524 */
2527 istmt->all_privs, istmt->privileges,
2530 parname,
2531 0, NULL);
2532
2533 /*
2534 * Generate new ACL.
2535 */
2537 istmt->grant_option, istmt->behavior,
2538 istmt->grantees, this_privileges,
2539 grantorId, ownerId);
2540
2541 /*
2542 * We need the members of both old and new ACLs so we can correct the
2543 * shared dependency information.
2544 */
2546
2547 /*
2548 * If the new ACL is equal to the default, we don't need the catalog
2549 * entry any longer. Delete it rather than updating it, to avoid
2550 * leaving a degenerate entry.
2551 */
2552 if (aclequal(new_acl, acldefault(istmt->objtype, ownerId)))
2553 {
2554 CatalogTupleDelete(relation, &tuple->t_self);
2555 }
2556 else
2557 {
2558 /* finished building new ACL value, now insert it */
2559 HeapTuple newtuple;
2561 bool nulls[Natts_pg_parameter_acl] = {0};
2562 bool replaces[Natts_pg_parameter_acl] = {0};
2563
2566
2567 newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation),
2568 values, nulls, replaces);
2569
2570 CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
2571 }
2572
2573 /* Update initial privileges for extensions */
2575 new_acl);
2576
2577 /* Update the shared dependency ACL info */
2579 ownerId,
2582
2583 ReleaseSysCache(tuple);
2584 pfree(new_acl);
2585
2586 /* prevent error when processing duplicate objects */
2588 }
2589
2590 table_close(relation, RowExclusiveLock);
2591}
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:220

References ACL_ALL_RIGHTS_PARAMETER_ACL, ACL_NO_RIGHTS, acldefault(), aclequal(), aclmembers(), InternalGrant::all_privs, InternalGrant::behavior, CatalogTupleDelete(), CatalogTupleUpdate(), CommandCounterIncrement(), DatumGetAclPCopy, elog, ERROR, fb(), GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, 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 1801 of file aclchk.c.

1802{
1803 Relation relation;
1805 ListCell *cell;
1806
1809
1810 foreach(cell, istmt->objects)
1811 {
1812 Oid relOid = lfirst_oid(cell);
1815 bool isNull;
1820 Acl *old_acl;
1822 int noldmembers;
1823 Oid *oldmembers;
1824 Oid ownerId;
1825 HeapTuple tuple;
1827
1829 if (!HeapTupleIsValid(tuple))
1830 elog(ERROR, "cache lookup failed for relation %u", relOid);
1832
1833 /* Not sensible to grant on an index */
1834 if (pg_class_tuple->relkind == RELKIND_INDEX ||
1836 ereport(ERROR,
1838 errmsg("\"%s\" is an index",
1839 NameStr(pg_class_tuple->relname))));
1840
1841 /* Composite types aren't tables either */
1842 if (pg_class_tuple->relkind == RELKIND_COMPOSITE_TYPE)
1843 ereport(ERROR,
1845 errmsg("\"%s\" is a composite type",
1846 NameStr(pg_class_tuple->relname))));
1847
1848 /* Used GRANT SEQUENCE on a non-sequence? */
1849 if (istmt->objtype == OBJECT_SEQUENCE &&
1850 pg_class_tuple->relkind != RELKIND_SEQUENCE)
1851 ereport(ERROR,
1853 errmsg("\"%s\" is not a sequence",
1854 NameStr(pg_class_tuple->relname))));
1855
1856 if (istmt->objtype == OBJECT_PROPGRAPH &&
1858 ereport(ERROR,
1860 errmsg("\"%s\" is not a property graph",
1861 NameStr(pg_class_tuple->relname))));
1862
1863 /* Adjust the default permissions based on object type */
1864 if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS)
1865 {
1866 if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
1868 else if (pg_class_tuple->relkind == RELKIND_PROPGRAPH)
1870 else
1872 }
1873 else
1874 this_privileges = istmt->privileges;
1875
1876 /*
1877 * The GRANT TABLE syntax can be used for sequences and non-sequences,
1878 * so we have to look at the relkind to determine the supported
1879 * permissions. The OR of table and sequence permissions were already
1880 * checked.
1881 */
1882 if (istmt->objtype == OBJECT_TABLE)
1883 {
1884 if (pg_class_tuple->relkind == RELKIND_SEQUENCE)
1885 {
1886 /*
1887 * For backward compatibility, just throw a warning for
1888 * invalid sequence permissions when using the non-sequence
1889 * GRANT syntax.
1890 */
1892 {
1893 /*
1894 * Mention the object name because the user needs to know
1895 * which operations succeeded. This is required because
1896 * WARNING allows the command to continue.
1897 */
1900 errmsg("sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges",
1901 NameStr(pg_class_tuple->relname))));
1903 }
1904 }
1905 else
1906 {
1908 {
1909 /*
1910 * USAGE is the only permission supported by sequences but
1911 * not by non-sequences. Don't mention the object name
1912 * because we didn't in the combined TABLE | SEQUENCE
1913 * check.
1914 */
1915 ereport(ERROR,
1917 errmsg("invalid privilege type %s for table",
1918 "USAGE")));
1919 }
1920 }
1921 }
1922
1923 /*
1924 * Set up array in which we'll accumulate any column privilege bits
1925 * that need modification. The array is indexed such that entry [0]
1926 * corresponds to FirstLowInvalidHeapAttributeNumber.
1927 */
1930 have_col_privileges = false;
1931
1932 /*
1933 * If we are revoking relation privileges that are also column
1934 * privileges, we must implicitly revoke them from each column too,
1935 * per SQL spec. (We don't need to implicitly add column privileges
1936 * during GRANT because the permissions-checking code always checks
1937 * both relation and per-column privileges.)
1938 */
1939 if (!istmt->is_grant &&
1941 {
1946 have_col_privileges = true;
1947 }
1948
1949 /*
1950 * Get owner ID and working copy of existing ACL. If there's no ACL,
1951 * substitute the proper default.
1952 */
1953 ownerId = pg_class_tuple->relowner;
1955 &isNull);
1956 if (isNull)
1957 {
1958 switch (pg_class_tuple->relkind)
1959 {
1960 case RELKIND_SEQUENCE:
1962 break;
1963 case RELKIND_PROPGRAPH:
1965 break;
1966 default:
1967 old_acl = acldefault(OBJECT_TABLE, ownerId);
1968 break;
1969 }
1970 /* There are no old member roles according to the catalogs */
1971 noldmembers = 0;
1972 oldmembers = NULL;
1973 }
1974 else
1975 {
1977 /* Get the roles mentioned in the existing ACL */
1979 }
1980
1981 /* Need an extra copy of original rel ACL for column handling */
1983
1984 /*
1985 * Handle relation-level privileges, if any were specified
1986 */
1988 {
1990 Acl *new_acl;
1991 Oid grantorId;
1992 HeapTuple newtuple;
1994 bool nulls[Natts_pg_class] = {0};
1995 bool replaces[Natts_pg_class] = {0};
1996 int nnewmembers;
1997 Oid *newmembers;
1998 ObjectType objtype;
1999
2000 /* Determine ID to do the grant as, and available grant options */
2002 old_acl, ownerId,
2004
2005 switch (pg_class_tuple->relkind)
2006 {
2007 case RELKIND_SEQUENCE:
2008 objtype = OBJECT_SEQUENCE;
2009 break;
2010 default:
2011 objtype = OBJECT_TABLE;
2012 break;
2013 }
2014
2015 /*
2016 * Restrict the privileges to what we can actually grant, and emit
2017 * the standards-mandated warning and error messages.
2018 */
2021 istmt->all_privs, this_privileges,
2022 relOid, grantorId, objtype,
2023 NameStr(pg_class_tuple->relname),
2024 0, NULL);
2025
2026 /*
2027 * Generate new ACL.
2028 */
2030 istmt->is_grant,
2031 istmt->grant_option,
2032 istmt->behavior,
2033 istmt->grantees,
2035 grantorId,
2036 ownerId);
2037
2038 /*
2039 * We need the members of both old and new ACLs so we can correct
2040 * the shared dependency information.
2041 */
2043
2044 /* finished building new ACL value, now insert it */
2045 replaces[Anum_pg_class_relacl - 1] = true;
2047
2048 newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation),
2049 values, nulls, replaces);
2050
2051 CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
2052 UnlockTuple(relation, &tuple->t_self, InplaceUpdateTupleLock);
2053
2054 /* Update initial privileges for extensions */
2056
2057 /* Update the shared dependency ACL info */
2059 ownerId,
2062
2063 pfree(new_acl);
2064 }
2065 else
2066 UnlockTuple(relation, &tuple->t_self, InplaceUpdateTupleLock);
2067
2068 /*
2069 * Handle column-level privileges, if any were specified or implied.
2070 * We first expand the user-specified column privileges into the
2071 * array, and then iterate over all nonempty array entries.
2072 */
2073 foreach(cell_colprivs, istmt->col_privs)
2074 {
2075 AccessPriv *col_privs = (AccessPriv *) lfirst(cell_colprivs);
2076
2077 if (col_privs->priv_name == NULL)
2079 else
2081
2083 ereport(ERROR,
2085 errmsg("invalid privilege type %s for column",
2087
2088 if (pg_class_tuple->relkind == RELKIND_SEQUENCE &&
2090 {
2091 /*
2092 * The only column privilege allowed on sequences is SELECT.
2093 * This is a warning not error because we do it that way for
2094 * relation-level privileges.
2095 */
2098 errmsg("sequence \"%s\" only supports SELECT column privileges",
2099 NameStr(pg_class_tuple->relname))));
2100
2102 }
2103
2104 expand_col_privileges(col_privs->cols, relOid,
2108 have_col_privileges = true;
2109 }
2110
2112 {
2113 AttrNumber i;
2114
2115 for (i = 0; i < num_col_privileges; i++)
2116 {
2118 continue;
2119 ExecGrant_Attribute(istmt,
2120 relOid,
2121 NameStr(pg_class_tuple->relname),
2123 ownerId,
2126 old_rel_acl);
2127 }
2128 }
2129
2132
2133 ReleaseSysCache(tuple);
2134
2135 /* prevent error when processing duplicate objects */
2137 }
2138
2140 table_close(relation, RowExclusiveLock);
2141}
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:1610
static void expand_col_privileges(List *colnames, Oid table_oid, AclMode this_privileges, AclMode *col_privileges, int num_col_privileges)
Definition aclchk.c:1577
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:1656
int16 AttrNumber
Definition attnum.h:21
#define WARNING
Definition elog.h:36
int i
Definition isn.c:77
void * palloc0(Size size)
Definition mcxt.c:1417
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(), GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, 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 2432 of file aclchk.c.

2433{
2435
2437
2438 /* Disallow GRANT on dependent types */
2440 ereport(ERROR,
2442 errmsg("cannot set privileges of array types"),
2443 errhint("Set the privileges of the element type instead.")));
2444 if (pg_type_tuple->typtype == TYPTYPE_MULTIRANGE)
2445 ereport(ERROR,
2447 errmsg("cannot set privileges of multirange types"),
2448 errhint("Set the privileges of the range type instead.")));
2449}
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 608 of file aclchk.c.

609{
610 switch (istmt->objtype)
611 {
612 case OBJECT_TABLE:
613 case OBJECT_SEQUENCE:
614 case OBJECT_PROPGRAPH:
615 ExecGrant_Relation(istmt);
616 break;
617 case OBJECT_DATABASE:
619 break;
620 case OBJECT_DOMAIN:
621 case OBJECT_TYPE:
623 break;
624 case OBJECT_FDW:
626 break;
629 break;
630 case OBJECT_FUNCTION:
631 case OBJECT_PROCEDURE:
632 case OBJECT_ROUTINE:
634 break;
635 case OBJECT_LANGUAGE:
637 break;
640 break;
641 case OBJECT_SCHEMA:
643 break;
646 break;
648 ExecGrant_Parameter(istmt);
649 break;
650 default:
651 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
652 (int) istmt->objtype);
653 }
654
655 /*
656 * Pass the info to event triggers about the just-executed GRANT. Note
657 * that we prefer to do it after actually executing it, because that gives
658 * the functions a chance to adjust the istmt with privileges actually
659 * granted.
660 */
663}
#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:2432
static void ExecGrant_common(InternalGrant *istmt, Oid classid, AclMode default_privs, void(*object_check)(InternalGrant *istmt, HeapTuple tuple))
Definition aclchk.c:2144
static void ExecGrant_Largeobject(InternalGrant *istmt)
Definition aclchk.c:2296
static void ExecGrant_Parameter(InternalGrant *istmt)
Definition aclchk.c:2452
static void ExecGrant_Relation(InternalGrant *istmt)
Definition aclchk.c:1801
static void ExecGrant_Language_check(InternalGrant *istmt, HeapTuple tuple)
Definition aclchk.c:2280
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 394 of file aclchk.c.

395{
396 InternalGrant istmt;
397 ListCell *cell;
398 const char *errormsg;
400
401 if (stmt->grantor)
402 {
403 Oid grantor;
404
405 grantor = get_rolespec_oid(stmt->grantor, false);
406
407 /*
408 * Currently, this clause is only for SQL compatibility, not very
409 * interesting otherwise.
410 */
411 if (grantor != GetUserId())
414 errmsg("grantor must be current user")));
415 }
416
417 /*
418 * Turn the regular GrantStmt into the InternalGrant form.
419 */
420 istmt.is_grant = stmt->is_grant;
421 istmt.objtype = stmt->objtype;
422
423 /* Collect the OIDs of the target objects */
424 switch (stmt->targtype)
425 {
427 istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects,
428 stmt->is_grant);
429 break;
431 istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects);
432 break;
433 /* ACL_TARGET_DEFAULTS should not be seen here */
434 default:
435 elog(ERROR, "unrecognized GrantStmt.targtype: %d",
436 (int) stmt->targtype);
437 }
438
439 /* all_privs to be filled below */
440 /* privileges to be filled below */
441 istmt.col_privs = NIL; /* may get filled below */
442 istmt.grantees = NIL; /* filled below */
443 istmt.grant_option = stmt->grant_option;
444 istmt.behavior = stmt->behavior;
445
446 /*
447 * Convert the RoleSpec list into an Oid list. Note that at this point we
448 * insert an ACL_ID_PUBLIC into the list if appropriate, so downstream
449 * there shouldn't be any additional work needed to support this case.
450 */
451 foreach(cell, stmt->grantees)
452 {
453 RoleSpec *grantee = (RoleSpec *) lfirst(cell);
455
456 switch (grantee->roletype)
457 {
458 case ROLESPEC_PUBLIC:
460 break;
461 default:
463 break;
464 }
466 }
467
468 /*
469 * Convert stmt->privileges, a list of AccessPriv nodes, into an AclMode
470 * bitmask. Note: objtype can't be OBJECT_COLUMN.
471 */
472 switch (stmt->objtype)
473 {
474 case OBJECT_TABLE:
475
476 /*
477 * Because this might be a sequence, we test both relation and
478 * sequence bits, and later do a more limited test when we know
479 * the object type.
480 */
482 errormsg = gettext_noop("invalid privilege type %s for relation");
483 break;
484 case OBJECT_SEQUENCE:
486 errormsg = gettext_noop("invalid privilege type %s for sequence");
487 break;
488 case OBJECT_DATABASE:
490 errormsg = gettext_noop("invalid privilege type %s for database");
491 break;
492 case OBJECT_DOMAIN:
494 errormsg = gettext_noop("invalid privilege type %s for domain");
495 break;
496 case OBJECT_FUNCTION:
498 errormsg = gettext_noop("invalid privilege type %s for function");
499 break;
500 case OBJECT_LANGUAGE:
502 errormsg = gettext_noop("invalid privilege type %s for language");
503 break;
506 errormsg = gettext_noop("invalid privilege type %s for large object");
507 break;
508 case OBJECT_SCHEMA:
510 errormsg = gettext_noop("invalid privilege type %s for schema");
511 break;
512 case OBJECT_PROCEDURE:
514 errormsg = gettext_noop("invalid privilege type %s for procedure");
515 break;
516 case OBJECT_ROUTINE:
518 errormsg = gettext_noop("invalid privilege type %s for routine");
519 break;
522 errormsg = gettext_noop("invalid privilege type %s for tablespace");
523 break;
524 case OBJECT_TYPE:
526 errormsg = gettext_noop("invalid privilege type %s for type");
527 break;
528 case OBJECT_FDW:
530 errormsg = gettext_noop("invalid privilege type %s for foreign-data wrapper");
531 break;
534 errormsg = gettext_noop("invalid privilege type %s for foreign server");
535 break;
538 errormsg = gettext_noop("invalid privilege type %s for parameter");
539 break;
540 case OBJECT_PROPGRAPH:
542 errormsg = gettext_noop("invalid privilege type %s for property graph");
543 break;
544 default:
545 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
546 (int) stmt->objtype);
547 /* keep compiler quiet */
549 errormsg = NULL;
550 }
551
552 if (stmt->privileges == NIL)
553 {
554 istmt.all_privs = true;
555
556 /*
557 * will be turned into ACL_ALL_RIGHTS_* by the internal routines
558 * depending on the object type
559 */
561 }
562 else
563 {
564 istmt.all_privs = false;
566
567 foreach(cell, stmt->privileges)
568 {
570 AclMode priv;
571
572 /*
573 * If it's a column-level specification, we just set it aside in
574 * col_privs for the moment; but insist it's for a relation.
575 */
576 if (privnode->cols)
577 {
578 if (stmt->objtype != OBJECT_TABLE)
581 errmsg("column privileges are only valid for relations")));
582 istmt.col_privs = lappend(istmt.col_privs, privnode);
583 continue;
584 }
585
586 if (privnode->priv_name == NULL) /* parser mistake? */
587 elog(ERROR, "AccessPriv node must specify privilege or columns");
588 priv = string_to_privilege(privnode->priv_name);
589
590 if (priv & ~all_privileges)
593 errmsg(errormsg, privilege_to_string(priv))));
594
595 istmt.privileges |= priv;
596 }
597 }
598
599 ExecGrantStmt_oids(&istmt);
600}
static void ExecGrantStmt_oids(InternalGrant *istmt)
Definition aclchk.c:608
static List * objectNamesToOids(ObjectType objtype, List *objnames, bool is_grant)
Definition aclchk.c:685
static List * objectsInSchemaToOids(ObjectType objtype, List *nspnames)
Definition aclchk.c:798
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, GetUserId(), InternalGrant::grant_option, InternalGrant::grantees, 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 1610 of file aclchk.c.

1614{
1616
1619 curr_att <= classForm->relnatts;
1620 curr_att++)
1621 {
1623 bool isdropped;
1624
1626 continue;
1627
1628 /* Views don't have any system columns at all */
1629 if (classForm->relkind == RELKIND_VIEW && curr_att < 0)
1630 continue;
1631
1636 elog(ERROR, "cache lookup failed for attribute %d of relation %u",
1638
1639 isdropped = ((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped;
1640
1642
1643 /* ignore dropped columns */
1644 if (isdropped)
1645 continue;
1646
1648 }
1649}
#define InvalidAttrNumber
Definition attnum.h:23
#define Assert(condition)
Definition c.h:945

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

1581{
1582 ListCell *cell;
1583
1584 foreach(cell, colnames)
1585 {
1586 char *colname = strVal(lfirst(cell));
1588
1589 attnum = get_attnum(table_oid, colname);
1591 ereport(ERROR,
1593 errmsg("column \"%s\" of relation \"%s\" does not exist",
1594 colname, get_rel_name(table_oid))));
1597 elog(ERROR, "column number out of range"); /* safety check */
1599 }
1600}
char * get_rel_name(Oid relid)
Definition lsyscache.c:2148
AttrNumber get_attnum(Oid relid, const char *attname)
Definition lsyscache.c:977
#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 4266 of file aclchk.c.

4267{
4268 Acl *result = NULL;
4269 HeapTuple tuple;
4270
4272 ObjectIdGetDatum(roleId),
4274 CharGetDatum(objtype));
4275
4276 if (HeapTupleIsValid(tuple))
4277 {
4279 bool isNull;
4280
4283 &isNull);
4284 if (!isNull)
4285 result = DatumGetAclPCopy(aclDatum);
4286 ReleaseSysCache(tuple);
4287 }
4288
4289 return result;
4290}
static Datum CharGetDatum(char X)
Definition postgres.h:132
HeapTuple SearchSysCache3(SysCacheIdentifier cacheId, Datum key1, Datum key2, Datum key3)
Definition syscache.c:240

References CharGetDatum(), DatumGetAclPCopy, fb(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), 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 4301 of file aclchk.c.

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

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

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

◆ getRelationsInNamespace()

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

Definition at line 891 of file aclchk.c.

892{
893 List *relations = NIL;
894 ScanKeyData key[2];
895 Relation rel;
896 TableScanDesc scan;
897 HeapTuple tuple;
898
899 ScanKeyInit(&key[0],
903 ScanKeyInit(&key[1],
906 CharGetDatum(relkind));
907
909 scan = table_beginscan_catalog(rel, 2, key);
910
911 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
912 {
913 Oid oid = ((Form_pg_class) GETSTRUCT(tuple))->oid;
914
915 relations = lappend_oid(relations, oid);
916 }
917
918 table_endscan(scan);
920
921 return relations;
922}
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition heapam.c:1420
#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:1004

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

4243{
4244 bool result = false;
4246
4247 /* Superusers bypass all permission checking. */
4248 if (superuser_arg(roleid))
4249 return true;
4250
4253 {
4256 }
4257 return result;
4258}
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(), 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 4223 of file aclchk.c.

4224{
4225 bool result = false;
4227
4228 /* Superusers bypass all permission checking. */
4229 if (superuser_arg(roleid))
4230 return true;
4231
4234 {
4237 }
4238 return result;
4239}
bool rolcreaterole
Definition pg_authid.h:39

References fb(), Form_pg_authid, GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), ReleaseSysCache(), 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 181 of file aclchk.c.

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

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

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

◆ object_aclcheck()

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

Definition at line 3890 of file aclchk.c.

3891{
3892 return object_aclcheck_ext(classid, objectid, roleid, mode, NULL);
3893}
AclResult object_aclcheck_ext(Oid classid, Oid objectid, Oid roleid, AclMode mode, bool *is_missing)
Definition aclchk.c:3900
static PgChecksumMode mode

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

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

3084{
3085 return object_aclmask_ext(classid, objectid, roleid, mask, how, NULL);
3086}

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

3096{
3098 AclMode result;
3099 HeapTuple tuple;
3101 bool isNull;
3102 Acl *acl;
3103 Oid ownerId;
3104
3105 /* Special cases */
3106 switch (classid)
3107 {
3109 return pg_namespace_aclmask_ext(objectid, roleid, mask, how,
3110 is_missing);
3111 case TypeRelationId:
3112 return pg_type_aclmask_ext(objectid, roleid, mask, how,
3113 is_missing);
3114 }
3115
3116 /* Even more special cases */
3117 Assert(classid != RelationRelationId); /* should use pg_class_acl* */
3118 Assert(classid != LargeObjectMetadataRelationId); /* should use
3119 * pg_largeobject_acl* */
3120
3121 /* Superusers bypass all permission checking. */
3122 if (superuser_arg(roleid))
3123 return mask;
3124
3125 /*
3126 * Get the object's ACL from its catalog
3127 */
3128
3130
3132 if (!HeapTupleIsValid(tuple))
3133 {
3134 if (is_missing != NULL)
3135 {
3136 /* return "no privileges" instead of throwing an error */
3137 *is_missing = true;
3138 return 0;
3139 }
3140 else
3141 elog(ERROR, "cache lookup failed for %s %u",
3143 }
3144
3146 tuple,
3147 get_object_attnum_owner(classid)));
3148
3150 &isNull);
3151 if (isNull)
3152 {
3153 /* No ACL, so build default ACL */
3154 acl = acldefault(get_object_type(classid, objectid), ownerId);
3155 aclDatum = (Datum) 0;
3156 }
3157 else
3158 {
3159 /* detoast ACL if necessary */
3160 acl = DatumGetAclP(aclDatum);
3161 }
3162
3163 result = aclmask(acl, roleid, ownerId, mask, how);
3164
3165 /* if we have a detoasted copy, free it */
3166 if (acl && acl != DatumGetPointer(aclDatum))
3167 pfree(acl);
3168
3169 ReleaseSysCache(tuple);
3170
3171 return result;
3172}
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Definition acl.c:1416
#define DatumGetAclP(X)
Definition acl.h:120
static AclMode pg_namespace_aclmask_ext(Oid nsp_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3662
static AclMode pg_type_aclmask_ext(Oid type_oid, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3764
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(), 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 4144 of file aclchk.c.

4145{
4147 Oid ownerId;
4148
4149 /* Superusers bypass all permission checking. */
4150 if (superuser_arg(roleid))
4151 return true;
4152
4153 /* For large objects, the catalog to consult is pg_largeobject_metadata */
4154 if (classid == LargeObjectRelationId)
4156
4159 {
4160 /* we can get the object's tuple from the syscache */
4161 HeapTuple tuple;
4162
4164 if (!HeapTupleIsValid(tuple))
4165 elog(ERROR, "cache lookup failed for %s %u",
4167
4169 tuple,
4170 get_object_attnum_owner(classid)));
4171 ReleaseSysCache(tuple);
4172 }
4173 else
4174 {
4175 /* for catalogs without an appropriate syscache */
4176 Relation rel;
4177 ScanKeyData entry[1];
4178 SysScanDesc scan;
4179 HeapTuple tuple;
4180 bool isnull;
4181
4182 rel = table_open(classid, AccessShareLock);
4183
4184 ScanKeyInit(&entry[0],
4185 get_object_attnum_oid(classid),
4188
4189 scan = systable_beginscan(rel,
4190 get_object_oid_index(classid), true,
4191 NULL, 1, entry);
4192
4193 tuple = systable_getnext(scan);
4194 if (!HeapTupleIsValid(tuple))
4195 elog(ERROR, "could not find tuple for %s %u",
4197
4198 ownerId = DatumGetObjectId(heap_getattr(tuple,
4199 get_object_attnum_owner(classid),
4200 RelationGetDescr(rel),
4201 &isnull));
4202 Assert(!isnull);
4203
4204 systable_endscan(scan);
4206 }
4207
4208 return has_privs_of_role(roleid, ownerId);
4209}
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 685 of file aclchk.c.

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

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

Referenced by ExecuteGrantStmt().

◆ objectsInSchemaToOids()

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

Definition at line 798 of file aclchk.c.

799{
800 List *objects = NIL;
801 ListCell *cell;
802
803 foreach(cell, nspnames)
804 {
805 char *nspname = strVal(lfirst(cell));
807 List *objs;
808
809 namespaceId = LookupExplicitNamespace(nspname, false);
810
811 switch (objtype)
812 {
813 case OBJECT_TABLE:
815 objects = list_concat(objects, objs);
817 objects = list_concat(objects, objs);
819 objects = list_concat(objects, objs);
821 objects = list_concat(objects, objs);
823 objects = list_concat(objects, objs);
824 break;
825 case OBJECT_SEQUENCE:
827 objects = list_concat(objects, objs);
828 break;
829 case OBJECT_PROPGRAPH:
831 objects = list_concat(objects, objs);
832 break;
833 case OBJECT_FUNCTION:
834 case OBJECT_PROCEDURE:
835 case OBJECT_ROUTINE:
836 {
837 ScanKeyData key[2];
838 int keycount;
839 Relation rel;
840 TableScanDesc scan;
841 HeapTuple tuple;
842
843 keycount = 0;
844 ScanKeyInit(&key[keycount++],
848
849 if (objtype == OBJECT_FUNCTION)
850 /* includes aggregates and window functions */
851 ScanKeyInit(&key[keycount++],
855 else if (objtype == OBJECT_PROCEDURE)
856 ScanKeyInit(&key[keycount++],
860
862 scan = table_beginscan_catalog(rel, keycount, key);
863
864 while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
865 {
866 Oid oid = ((Form_pg_proc) GETSTRUCT(tuple))->oid;
867
868 objects = lappend_oid(objects, oid);
869 }
870
871 table_endscan(scan);
873 }
874 break;
875 default:
876 /* should not happen */
877 elog(ERROR, "unrecognized GrantStmt.objtype: %d",
878 (int) objtype);
879 }
880 }
881
882 return objects;
883}
static List * getRelationsInNamespace(Oid namespaceId, char relkind)
Definition aclchk.c:891
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 3020 of file aclchk.c.

3022{
3023 switch (objtype)
3024 {
3025 case OBJECT_COLUMN:
3026 return
3027 pg_class_aclmask(object_oid, roleid, mask, how) |
3028 pg_attribute_aclmask(object_oid, attnum, roleid, mask, how);
3029 case OBJECT_TABLE:
3030 case OBJECT_SEQUENCE:
3031 case OBJECT_PROPGRAPH:
3032 return pg_class_aclmask(object_oid, roleid, mask, how);
3033 case OBJECT_DATABASE:
3034 return object_aclmask(DatabaseRelationId, object_oid, roleid, mask, how);
3035 case OBJECT_FUNCTION:
3036 return object_aclmask(ProcedureRelationId, object_oid, roleid, mask, how);
3037 case OBJECT_LANGUAGE:
3038 return object_aclmask(LanguageRelationId, object_oid, roleid, mask, how);
3039 case OBJECT_LARGEOBJECT:
3041 mask, how, NULL);
3043 return pg_parameter_acl_aclmask(object_oid, roleid, mask, how);
3044 case OBJECT_SCHEMA:
3045 return object_aclmask(NamespaceRelationId, object_oid, roleid, mask, how);
3047 elog(ERROR, "grantable rights not supported for statistics objects");
3048 /* not reached, but keep compiler quiet */
3049 return ACL_NO_RIGHTS;
3050 case OBJECT_TABLESPACE:
3051 return object_aclmask(TableSpaceRelationId, object_oid, roleid, mask, how);
3052 case OBJECT_FDW:
3055 return object_aclmask(ForeignServerRelationId, object_oid, roleid, mask, how);
3057 elog(ERROR, "grantable rights not supported for event triggers");
3058 /* not reached, but keep compiler quiet */
3059 return ACL_NO_RIGHTS;
3060 case OBJECT_TYPE:
3061 return object_aclmask(TypeRelationId, object_oid, roleid, mask, how);
3062 default:
3063 elog(ERROR, "unrecognized object type: %d",
3064 (int) objtype);
3065 /* not reached, but keep compiler quiet */
3066 return ACL_NO_RIGHTS;
3067 }
3068}
static AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, AclMode mask, AclMaskHow how, Snapshot snapshot)
Definition aclchk.c:3571
static AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3183
static AclMode pg_parameter_acl_aclmask(Oid acl_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3512
static AclMode object_aclmask(Oid classid, Oid objectid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3082
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3308

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

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

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

3966{
3968}
AclResult pg_attribute_aclcheck_all_ext(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3975

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

3978{
3979 AclResult result;
3982 Oid ownerId;
3983 AttrNumber nattrs;
3985
3986 /*
3987 * Must fetch pg_class row to get owner ID and number of attributes.
3988 */
3991 {
3992 if (is_missing != NULL)
3993 {
3994 /* return "no privileges" instead of throwing an error */
3995 *is_missing = true;
3996 return ACLCHECK_NO_PRIV;
3997 }
3998 else
3999 ereport(ERROR,
4001 errmsg("relation with OID %u does not exist",
4002 table_oid)));
4003 }
4005
4006 ownerId = classForm->relowner;
4007 nattrs = classForm->relnatts;
4008
4010
4011 /*
4012 * Initialize result in case there are no non-dropped columns. We want to
4013 * report failure in such cases for either value of 'how'.
4014 */
4015 result = ACLCHECK_NO_PRIV;
4016
4017 for (curr_att = 1; curr_att <= nattrs; curr_att++)
4018 {
4021 bool isNull;
4022 Acl *acl;
4024
4028
4029 /*
4030 * Lookup failure probably indicates that the table was just dropped,
4031 * but we'll treat it the same as a dropped column rather than
4032 * throwing error.
4033 */
4035 continue;
4036
4037 /* ignore dropped columns */
4038 if (((Form_pg_attribute) GETSTRUCT(attTuple))->attisdropped)
4039 {
4041 continue;
4042 }
4043
4045 &isNull);
4046
4047 /*
4048 * Here we hard-wire knowledge that the default ACL for a column
4049 * grants no privileges, so that we can fall out quickly in the very
4050 * common case where attacl is null.
4051 */
4052 if (isNull)
4053 attmask = 0;
4054 else
4055 {
4056 /* detoast column's ACL if necessary */
4057 acl = DatumGetAclP(aclDatum);
4058
4059 attmask = aclmask(acl, roleid, ownerId, mode, ACLMASK_ANY);
4060
4061 /* if we have a detoasted copy, free it */
4062 if (acl != DatumGetPointer(aclDatum))
4063 pfree(acl);
4064 }
4065
4067
4068 if (attmask != 0)
4069 {
4070 result = ACLCHECK_OK;
4071 if (how == ACLMASK_ANY)
4072 break; /* succeed on any success */
4073 }
4074 else
4075 {
4076 result = ACLCHECK_NO_PRIV;
4077 if (how == ACLMASK_ALL)
4078 break; /* fail on any failure */
4079 }
4080 }
4081
4082 return result;
4083}
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(), 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 3934 of file aclchk.c.

3936{
3938 ACLMASK_ANY, is_missing) != 0)
3939 return ACLCHECK_OK;
3940 else
3941 return ACLCHECK_NO_PRIV;
3942}
static AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how, bool *is_missing)
Definition aclchk.c:3194

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

3185{
3187 mask, how, NULL);
3188}

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

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

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

Referenced by pg_attribute_aclcheck_ext(), and pg_attribute_aclmask().

◆ pg_class_aclcheck()

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

3310{
3311 return pg_class_aclmask_ext(table_oid, roleid, mask, how, NULL);
3312}

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

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

References ACL_DELETE, ACL_INSERT, ACL_MAINTAIN, ACL_SELECT, ACL_TRUNCATE, ACL_UPDATE, ACL_USAGE, acldefault(), aclmask(), DatumGetAclP, DatumGetPointer(), ereport, errcode(), ERRCODE_UNDEFINED_TABLE, errmsg, ERROR, fb(), GETSTRUCT(), has_privs_of_role(), HeapTupleIsValid, IsSystemClass(), OBJECT_SEQUENCE, OBJECT_TABLE, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), 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 4130 of file aclchk.c.

4132{
4134 ACLMASK_ANY, snapshot) != 0)
4135 return ACLCHECK_OK;
4136 else
4137 return ACLCHECK_NO_PRIV;
4138}

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

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

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

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

References ACL_ALL_RIGHTS_SCHEMA, ACL_CREATE_TEMP, ACL_USAGE, ACLCHECK_OK, acldefault(), aclmask(), DatumGetAclP, DatumGetPointer(), ereport, errcode(), errmsg, ERROR, fb(), Form_pg_namespace, GETSTRUCT(), has_privs_of_role(), HeapTupleIsValid, isTempNamespace(), MyDatabaseId, object_aclcheck_ext(), OBJECT_SCHEMA, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), 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 3512 of file aclchk.c.

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

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer(), ereport, errcode(), errmsg, ERROR, fb(), HeapTupleIsValid, OBJECT_PARAMETER_ACL, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), 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 4118 of file aclchk.c.

4119{
4120 if (pg_parameter_aclmask(name, roleid, mode, ACLMASK_ANY) != 0)
4121 return ACLCHECK_OK;
4122 else
4123 return ACLCHECK_NO_PRIV;
4124}
static AclMode pg_parameter_aclmask(const char *name, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3448
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 3448 of file aclchk.c.

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

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

References acldefault(), aclmask(), DatumGetAclP, DatumGetPointer(), ereport, errcode(), errmsg, ERROR, fb(), Form_pg_type, get_multirange_range(), GETSTRUCT(), HeapTupleIsValid, OBJECT_TYPE, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), 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 2636 of file aclchk.c.

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

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

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

◆ recordDependencyOnNewAcl()

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

Definition at line 4381 of file aclchk.c.

4383{
4384 int nmembers;
4385 Oid *members;
4386
4387 /* Nothing to do if ACL is defaulted */
4388 if (acl == NULL)
4389 return;
4390
4391 /* Extract roles mentioned in ACL */
4392 nmembers = aclmembers(acl, &members);
4393
4394 /* Update the shared dependency ACL info */
4395 updateAclDependencies(classId, objectId, objsubId,
4396 ownerId,
4397 0, NULL,
4398 nmembers, members);
4399}

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

4656{
4657 /*
4658 * Generally, we only record the initial privileges when an extension is
4659 * being created, but because we don't actually use CREATE EXTENSION
4660 * during binary upgrades with pg_upgrade, there is a variable to let us
4661 * know that the GRANT and REVOKE statements being issued, while this
4662 * variable is true, are for the initial privileges of the extension
4663 * object and therefore we need to record them.
4664 */
4666 return;
4667
4668 recordExtensionInitPrivWorker(objoid, classoid, objsubid, new_acl);
4669}
static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_acl)
Definition aclchk.c:4684
bool binary_upgrade_record_init_privs
Definition aclchk.c:109
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 4684 of file aclchk.c.

4686{
4687 Relation relation;
4688 ScanKeyData key[3];
4689 SysScanDesc scan;
4690 HeapTuple tuple;
4691 HeapTuple oldtuple;
4692 int noldmembers;
4693 int nnewmembers;
4694 Oid *oldmembers;
4695 Oid *newmembers;
4696
4697 /* We'll need the role membership of the new ACL. */
4699
4700 /* Search pg_init_privs for an existing entry. */
4702
4703 ScanKeyInit(&key[0],
4706 ObjectIdGetDatum(objoid));
4707 ScanKeyInit(&key[1],
4710 ObjectIdGetDatum(classoid));
4711 ScanKeyInit(&key[2],
4714 Int32GetDatum(objsubid));
4715
4716 scan = systable_beginscan(relation, InitPrivsObjIndexId, true,
4717 NULL, 3, key);
4718
4719 /* There should exist only one entry or none. */
4720 oldtuple = systable_getnext(scan);
4721
4722 /* If we find an entry, update it with the latest ACL. */
4723 if (HeapTupleIsValid(oldtuple))
4724 {
4726 bool nulls[Natts_pg_init_privs] = {0};
4727 bool replace[Natts_pg_init_privs] = {0};
4729 bool isNull;
4730 Acl *old_acl;
4731
4732 /* Update pg_shdepend for roles mentioned in the old/new ACLs. */
4734 RelationGetDescr(relation), &isNull);
4735 Assert(!isNull);
4738
4739 updateInitAclDependencies(classoid, objoid, objsubid,
4742
4743 /* If we have a new ACL to set, then update the row with it. */
4744 if (new_acl && ACL_NUM(new_acl) != 0)
4745 {
4747 replace[Anum_pg_init_privs_initprivs - 1] = true;
4748
4749 oldtuple = heap_modify_tuple(oldtuple, RelationGetDescr(relation),
4750 values, nulls, replace);
4751
4752 CatalogTupleUpdate(relation, &oldtuple->t_self, oldtuple);
4753 }
4754 else
4755 {
4756 /* new_acl is NULL/empty, so delete the entry we found. */
4757 CatalogTupleDelete(relation, &oldtuple->t_self);
4758 }
4759 }
4760 else
4761 {
4763 bool nulls[Natts_pg_init_privs] = {0};
4764
4765 /*
4766 * Only add a new entry if the new ACL is non-NULL.
4767 *
4768 * If we are passed in a NULL ACL and no entry exists, we can just
4769 * fall through and do nothing.
4770 */
4771 if (new_acl && ACL_NUM(new_acl) != 0)
4772 {
4773 /* No entry found, so add it. */
4777
4778 /* This function only handles initial privileges of extensions */
4781
4783
4784 tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
4785
4786 CatalogTupleInsert(relation, tuple);
4787
4788 /* Update pg_shdepend, too. */
4789 noldmembers = 0;
4790 oldmembers = NULL;
4791
4792 updateInitAclDependencies(classoid, objoid, objsubid,
4795 }
4796 }
4797
4798 systable_endscan(scan);
4799
4800 /* prevent error when processing objects multiple times */
4802
4803 table_close(relation, RowExclusiveLock);
4804}
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1037
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 4408 of file aclchk.c.

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

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

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

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

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

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

1440{
1441 if (classid == DefaultAclRelationId)
1442 {
1445 Relation rel;
1446 ScanKeyData skey[1];
1447 SysScanDesc scan;
1448 HeapTuple tuple;
1449
1450 /* first fetch info needed by SetDefaultACL */
1452
1453 ScanKeyInit(&skey[0],
1456 ObjectIdGetDatum(objid));
1457
1458 scan = systable_beginscan(rel, DefaultAclOidIndexId, true,
1459 NULL, 1, skey);
1460
1461 tuple = systable_getnext(scan);
1462
1463 if (!HeapTupleIsValid(tuple))
1464 elog(ERROR, "could not find tuple for default ACL %u", objid);
1465
1467
1468 iacls.roleid = pg_default_acl_tuple->defaclrole;
1469 iacls.nspid = pg_default_acl_tuple->defaclnamespace;
1470
1471 switch (pg_default_acl_tuple->defaclobjtype)
1472 {
1473 case DEFACLOBJ_RELATION:
1474 iacls.objtype = OBJECT_TABLE;
1475 break;
1476 case DEFACLOBJ_SEQUENCE:
1477 iacls.objtype = OBJECT_SEQUENCE;
1478 break;
1479 case DEFACLOBJ_FUNCTION:
1480 iacls.objtype = OBJECT_FUNCTION;
1481 break;
1482 case DEFACLOBJ_TYPE:
1483 iacls.objtype = OBJECT_TYPE;
1484 break;
1486 iacls.objtype = OBJECT_SCHEMA;
1487 break;
1489 iacls.objtype = OBJECT_LARGEOBJECT;
1490 break;
1491 default:
1492 /* Shouldn't get here */
1493 elog(ERROR, "unexpected default ACL type: %d",
1494 (int) pg_default_acl_tuple->defaclobjtype);
1495 break;
1496 }
1497
1498 systable_endscan(scan);
1500
1501 iacls.is_grant = false;
1502 iacls.all_privs = true;
1503 iacls.privileges = ACL_NO_RIGHTS;
1504 iacls.grantees = list_make1_oid(roleid);
1505 iacls.grant_option = false;
1506 iacls.behavior = DROP_CASCADE;
1507
1508 /* Do it */
1510 }
1511 else
1512 {
1513 InternalGrant istmt;
1514
1515 switch (classid)
1516 {
1517 case RelationRelationId:
1518 /* it's OK to use TABLE for a sequence */
1519 istmt.objtype = OBJECT_TABLE;
1520 break;
1521 case DatabaseRelationId:
1522 istmt.objtype = OBJECT_DATABASE;
1523 break;
1524 case TypeRelationId:
1525 istmt.objtype = OBJECT_TYPE;
1526 break;
1528 istmt.objtype = OBJECT_ROUTINE;
1529 break;
1530 case LanguageRelationId:
1531 istmt.objtype = OBJECT_LANGUAGE;
1532 break;
1535 break;
1537 istmt.objtype = OBJECT_SCHEMA;
1538 break;
1540 istmt.objtype = OBJECT_TABLESPACE;
1541 break;
1544 break;
1546 istmt.objtype = OBJECT_FDW;
1547 break;
1550 break;
1551 default:
1552 elog(ERROR, "unexpected object class %u", classid);
1553 break;
1554 }
1555 istmt.is_grant = false;
1556 istmt.objects = list_make1_oid(objid);
1557 istmt.all_privs = true;
1558 istmt.privileges = ACL_NO_RIGHTS;
1559 istmt.col_privs = NIL;
1560 istmt.grantees = list_make1_oid(roleid);
1561 istmt.grant_option = false;
1562 istmt.behavior = DROP_CASCADE;
1563
1564 ExecGrantStmt_oids(&istmt);
1565 }
1566}
static void SetDefaultACL(InternalDefaultACL *iacls)
Definition aclchk.c:1164
@ 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, 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 4812 of file aclchk.c.

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

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

Referenced by shdepReassignOwned_InitAcl().

◆ restrict_and_check_grant()

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

Definition at line 240 of file aclchk.c.

244{
247
248 switch (objtype)
249 {
250 case OBJECT_COLUMN:
252 break;
253 case OBJECT_TABLE:
255 break;
256 case OBJECT_SEQUENCE:
258 break;
259 case OBJECT_DATABASE:
261 break;
262 case OBJECT_FUNCTION:
264 break;
265 case OBJECT_LANGUAGE:
267 break;
270 break;
271 case OBJECT_SCHEMA:
273 break;
276 break;
277 case OBJECT_FDW:
279 break;
282 break;
284 elog(ERROR, "grantable rights not supported for event triggers");
285 /* not reached, but keep compiler quiet */
286 return ACL_NO_RIGHTS;
287 case OBJECT_TYPE:
289 break;
292 break;
293 case OBJECT_PROPGRAPH:
295 break;
296 default:
297 elog(ERROR, "unrecognized object type: %d", objtype);
298 /* not reached, but keep compiler quiet */
299 return ACL_NO_RIGHTS;
300 }
301
302 /*
303 * If we found no grant options, consider whether to issue a hard error.
304 * Per spec, having any privilege at all on the object will get you by
305 * here.
306 */
308 {
309 if (pg_aclmask(objtype, objectId, att_number, grantorId,
312 {
313 if (objtype == OBJECT_COLUMN && colname)
314 aclcheck_error_col(ACLCHECK_NO_PRIV, objtype, objname, colname);
315 else
316 aclcheck_error(ACLCHECK_NO_PRIV, objtype, objname);
317 }
318 }
319
320 /*
321 * Restrict the operation to what we can actually grant or revoke, and
322 * issue a warning if appropriate. (For REVOKE this isn't quite what the
323 * spec says to do: the spec seems to want a warning only if no privilege
324 * bits actually change in the ACL. In practice that behavior seems much
325 * too noisy, as well as inconsistent with the GRANT case.)
326 */
328 if (is_grant)
329 {
330 if (this_privileges == 0)
331 {
332 if (objtype == OBJECT_COLUMN && colname)
335 errmsg("no privileges were granted for column \"%s\" of relation \"%s\"",
336 colname, objname)));
337 else
340 errmsg("no privileges were granted for \"%s\"",
341 objname)));
342 }
343 else if (!all_privs && this_privileges != privileges)
344 {
345 if (objtype == OBJECT_COLUMN && colname)
348 errmsg("not all privileges were granted for column \"%s\" of relation \"%s\"",
349 colname, objname)));
350 else
353 errmsg("not all privileges were granted for \"%s\"",
354 objname)));
355 }
356 }
357 else
358 {
359 if (this_privileges == 0)
360 {
361 if (objtype == OBJECT_COLUMN && colname)
364 errmsg("no privileges could be revoked for column \"%s\" of relation \"%s\"",
365 colname, objname)));
366 else
369 errmsg("no privileges could be revoked for \"%s\"",
370 objname)));
371 }
372 else if (!all_privs && this_privileges != privileges)
373 {
374 if (objtype == OBJECT_COLUMN && colname)
377 errmsg("not all privileges could be revoked for column \"%s\" of relation \"%s\"",
378 colname, objname)));
379 else
382 errmsg("not all privileges could be revoked for \"%s\"",
383 objname)));
384 }
385 }
386
387 return this_privileges;
388}
#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:2978
static AclMode pg_aclmask(ObjectType objtype, Oid object_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how)
Definition aclchk.c:3020

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

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

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

Referenced by RemoveRoleFromObjectACL(), and SetDefaultACLsInSchemas().

◆ SetDefaultACLsInSchemas()

static void SetDefaultACLsInSchemas ( InternalDefaultACL iacls,
List nspnames 
)
static

Definition at line 1122 of file aclchk.c.

1123{
1124 if (nspnames == NIL)
1125 {
1126 /* Set database-wide permissions if no schema was specified */
1127 iacls->nspid = InvalidOid;
1128
1130 }
1131 else
1132 {
1133 /* Look up the schema OIDs and set permissions for each one */
1135
1136 foreach(nspcell, nspnames)
1137 {
1138 char *nspname = strVal(lfirst(nspcell));
1139
1140 iacls->nspid = get_namespace_oid(nspname, false);
1141
1142 /*
1143 * We used to insist that the target role have CREATE privileges
1144 * on the schema, since without that it wouldn't be able to create
1145 * an object for which these default privileges would apply.
1146 * However, this check proved to be more confusing than helpful,
1147 * and it also caused certain database states to not be
1148 * dumpable/restorable, since revoking CREATE doesn't cause
1149 * default privileges for the schema to go away. So now, we just
1150 * allow the ALTER; if the user lacks CREATE he'll find out when
1151 * he tries to create an object.
1152 */
1153
1155 }
1156 }
1157}
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 2595 of file aclchk.c.

2596{
2597 if (strcmp(privname, "insert") == 0)
2598 return ACL_INSERT;
2599 if (strcmp(privname, "select") == 0)
2600 return ACL_SELECT;
2601 if (strcmp(privname, "update") == 0)
2602 return ACL_UPDATE;
2603 if (strcmp(privname, "delete") == 0)
2604 return ACL_DELETE;
2605 if (strcmp(privname, "truncate") == 0)
2606 return ACL_TRUNCATE;
2607 if (strcmp(privname, "references") == 0)
2608 return ACL_REFERENCES;
2609 if (strcmp(privname, "trigger") == 0)
2610 return ACL_TRIGGER;
2611 if (strcmp(privname, "execute") == 0)
2612 return ACL_EXECUTE;
2613 if (strcmp(privname, "usage") == 0)
2614 return ACL_USAGE;
2615 if (strcmp(privname, "create") == 0)
2616 return ACL_CREATE;
2617 if (strcmp(privname, "temporary") == 0)
2618 return ACL_CREATE_TEMP;
2619 if (strcmp(privname, "temp") == 0)
2620 return ACL_CREATE_TEMP;
2621 if (strcmp(privname, "connect") == 0)
2622 return ACL_CONNECT;
2623 if (strcmp(privname, "set") == 0)
2624 return ACL_SET;
2625 if (strcmp(privname, "alter system") == 0)
2626 return ACL_ALTER_SYSTEM;
2627 if (strcmp(privname, "maintain") == 0)
2628 return ACL_MAINTAIN;
2629 ereport(ERROR,
2631 errmsg("unrecognized privilege type \"%s\"", privname)));
2632 return 0; /* appease compiler */
2633}

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

Referenced by binary_upgrade_set_record_init_privs(), and recordExtensionInitPriv().