81 static const char *
getid(
const char *s,
char *n);
82 static void putid(
char *p,
const char *s);
140 bool in_quotes =
false;
144 while (isspace((
unsigned char) *s))
149 (isalnum((
unsigned char) *s) ||
160 in_quotes = !in_quotes;
170 (
errcode(ERRCODE_NAME_TOO_LONG),
171 errmsg(
"identifier too long"),
172 errdetail(
"Identifier must be less than %d characters.",
178 while (isspace((
unsigned char) *s))
194 for (src = s; *src; src++)
197 if (!isalnum((
unsigned char) *src) && *src !=
'_')
205 for (src = s; *src; src++)
252 if (strcmp(name,
"group") != 0 && strcmp(name,
"user") != 0)
254 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
255 errmsg(
"unrecognized key word: \"%s\"", name),
256 errhint(
"ACL key word must be \"group\" or \"user\".")));
260 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
262 errhint(
"A name must follow the \"group\" or \"user\" key word.")));
267 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
268 errmsg(
"missing \"=\" sign")));
272 for (++s, read = 0; isalpha((
unsigned char) *s) || *s ==
'*'; s++)
320 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
321 errmsg(
"invalid mode character: must be one of \"%s\"",
339 s =
getid(s + 1, name2);
340 if (name2[0] ==
'\0')
342 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
343 errmsg(
"a name must follow the \"/\" sign")));
350 (
errcode(ERRCODE_INVALID_GRANTOR),
351 errmsg(
"defaulting grantor to user ID %u",
352 BOOTSTRAP_SUPERUSERID)));
451 if (left_acl == NULL ||
ACL_NUM(left_acl) == 0)
453 if (right_acl == NULL ||
ACL_NUM(right_acl) == 0)
460 if (right_acl == NULL ||
ACL_NUM(right_acl) == 0)
465 result_acl =
aclcopy(left_acl);
470 for (i = 0; i < num; i++, aip++)
477 result_acl = tmp_acl;
489 if (acl != NULL &&
ACL_NUM(acl) > 1)
504 if (left_acl == NULL ||
ACL_NUM(left_acl) == 0)
506 if (right_acl == NULL ||
ACL_NUM(right_acl) == 0)
513 if (right_acl == NULL ||
ACL_NUM(right_acl) == 0)
536 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
537 errmsg(
"ACL array contains wrong data type")));
540 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
541 errmsg(
"ACL arrays must be one-dimensional")));
544 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
545 errmsg(
"ACL arrays must not contain null values")));
564 while (isspace((
unsigned char) *s))
568 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
569 errmsg(
"extra garbage at the end of the ACL specification")));
591 out =
palloc(strlen(
"=/") +
804 elog(
ERROR,
"unrecognized objtype: %d", (
int) objtype);
898 elog(
ERROR,
"unrecognized objtype abbreviation: %c", objtypec);
953 for (dst = 0; dst < num; ++dst)
960 memcpy(new_acl, old_acl,
ACL_SIZE(old_acl));
970 memcpy(new_aip, old_aip, num *
sizeof(
AclItem));
1008 memmove(new_aip + dst,
1010 (num - dst - 1) *
sizeof(
AclItem));
1020 if ((old_goptions & ~new_goptions) != 0)
1024 (old_goptions & ~new_goptions),
1051 bool newpresent =
false;
1068 memcpy(new_aip, old_aip, num *
sizeof(
AclItem));
1069 for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
1100 for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++)
1106 for (src = targ + 1, src_aip = targ_aip + 1; src < num;
1121 new_aip[dst] = *targ_aip;
1169 memcpy(acl, old_acl,
ACL_SIZE(old_acl));
1175 for (i = 0; i < num; i++)
1177 if (aip[i].ai_grantee == mod_aip->
ai_grantee &&
1203 (
errcode(ERRCODE_INVALID_GRANT_OPERATION),
1204 errmsg(
"grant options cannot be granted back to your own grantor")));
1240 if (grantee == ownerId)
1244 still_has =
aclmask(acl, grantee, ownerId,
1254 for (i = 0; i < num; i++)
1256 if (aip[i].ai_grantor == grantee
1264 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1265 errmsg(
"dependent privileges exist"),
1266 errhint(
"Use CASCADE to revoke them too.")));
1341 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1351 for (i = 0; i < num; i++)
1359 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1371 remaining = mask & ~result;
1372 for (i = 0; i < num; i++)
1380 if ((aidata->
ai_privs & remaining) &&
1384 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1386 remaining = mask & ~result;
1429 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1439 for (i = 0; i < num; i++)
1446 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1471 if (acl == NULL ||
ACL_NUM(acl) == 0)
1487 for (i = 0; i <
ACL_NUM(acl); i++)
1519 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1520 errmsg(
"aclinsert is no longer supported")));
1529 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1530 errmsg(
"aclremove is no longer supported")));
1547 for (i = 0; i < num; ++
i)
1615 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1616 errmsg(
"unrecognized privilege type: \"%s\"", priv_type)));
1640 for (chunk = priv_type; chunk; chunk = next_chunk)
1646 next_chunk = strchr(chunk,
',');
1648 *next_chunk++ =
'\0';
1651 while (*chunk && isspace((
unsigned char) *chunk))
1653 chunk_len = strlen(chunk);
1654 while (chunk_len > 0 && isspace((
unsigned char) chunk[chunk_len - 1]))
1656 chunk[chunk_len] =
'\0';
1659 for (this_priv = privileges; this_priv->
name; this_priv++)
1663 result |= this_priv->
value;
1667 if (!this_priv->
name)
1669 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1670 errmsg(
"unrecognized privilege type: \"%s\"", chunk)));
1694 return "REFERENCES";
1708 elog(
ERROR,
"unrecognized aclright: %d", aclright);
1763 idx = (
int *)
palloc(
sizeof(
int[2]));
1789 aidata = &aidat[idx[0]];
1790 priv_bit = 1 << idx[1];
1804 MemSet(nulls, 0,
sizeof(nulls));
2003 static const priv_map table_priv_map[] = {
2019 {
"RULE WITH GRANT OPTION", 0},
2058 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2059 errmsg(
"\"%s\" is not a sequence",
2088 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2089 errmsg(
"\"%s\" is not a sequence",
2116 if (relkind ==
'\0')
2118 else if (relkind != RELKIND_SEQUENCE)
2120 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2121 errmsg(
"\"%s\" is not a sequence",
2148 if (relkind ==
'\0')
2150 else if (relkind != RELKIND_SEQUENCE)
2152 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2153 errmsg(
"\"%s\" is not a sequence",
2180 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2181 errmsg(
"\"%s\" is not a sequence",
2206 if (relkind ==
'\0')
2208 else if (relkind != RELKIND_SEQUENCE)
2210 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2211 errmsg(
"\"%s\" is not a sequence",
2226 static const priv_map sequence_priv_map[] = {
2489 if (attributeForm->attisdropped)
2849 if (attributeForm->attisdropped)
2852 attnum = attributeForm->attnum;
2864 if (tablename != NULL)
2868 (
errcode(ERRCODE_UNDEFINED_COLUMN),
2869 errmsg(
"column \"%s\" of relation \"%s\" does not exist",
2870 colname, tablename)));
2887 static const priv_map column_priv_map[] = {
3084 static const priv_map database_priv_map[] = {
3282 static const priv_map foreign_data_wrapper_priv_map[] = {
3469 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3470 errmsg(
"function \"%s\" does not exist", funcname)));
3482 static const priv_map function_priv_map[] = {
3673 static const priv_map language_priv_map[] = {
3864 static const priv_map schema_priv_map[] = {
4057 static const priv_map server_priv_map[] = {
4248 static const priv_map tablespace_priv_map[] = {
4434 (
errcode(ERRCODE_UNDEFINED_OBJECT),
4435 errmsg(
"type \"%s\" does not exist", typname)));
4447 static const priv_map type_priv_map[] = {
4624 static const priv_map role_priv_map[] = {
4707 bool result =
false;
4739 List *new_cached_privs_roles;
4759 foreach(l, roles_list)
4772 for (i = 0; i < memlist->
n_members; i++)
4791 new_cached_privs_roles =
list_copy(roles_list);
4800 cached_privs_roles = new_cached_privs_roles;
4822 List *new_cached_membership_roles;
4842 foreach(l, roles_list)
4851 for (i = 0; i < memlist->
n_members; i++)
4870 new_cached_membership_roles =
list_copy(roles_list);
4879 cached_membership_roles = new_cached_membership_roles;
4945 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
4946 errmsg(
"must be member of role \"%s\"",
4979 bool result =
false;
5026 foreach(l, roles_list)
5035 for (i = 0; i < memlist->
n_members; i++)
5040 if (otherid == role &&
5104 const Acl *acl,
Oid ownerId,
5120 *grantorId = ownerId;
5121 *grantOptions = needed_goptions;
5134 *grantorId = roleId;
5138 foreach(l, roles_list)
5145 if (otherprivs == needed_goptions)
5148 *grantorId = otherrole;
5149 *grantOptions = otherprivs;
5161 if (nnewrights > nrights)
5163 *grantorId = otherrole;
5164 *grantOptions = otherprivs;
5165 nrights = nnewrights;
5186 (
errcode(ERRCODE_UNDEFINED_OBJECT),
5187 errmsg(
"role \"%s\" does not exist", rolname)));
5198 if (strcmp(rolname,
"public") == 0)
5234 (
errcode(ERRCODE_UNDEFINED_OBJECT),
5235 errmsg(
"role \"%s\" does not exist",
"public")));
5262 (
errcode(ERRCODE_UNDEFINED_OBJECT),
5281 (
errcode(ERRCODE_UNDEFINED_OBJECT),
5282 errmsg(
"role \"%s\" does not exist",
"public")));
5331 (
errcode(ERRCODE_RESERVED_NAME),
5332 errmsg(
"role name \"%s\" is reserved",
5337 (
errcode(ERRCODE_RESERVED_NAME),
5338 errmsg(
"role name \"%s\" is reserved",
bool InLocalUserIdChange(void)
Datum has_column_privilege_name_name_name(PG_FUNCTION_ARGS)
static void putid(char *p, const char *s)
Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)
Datum has_column_privilege_id_id_attnum(PG_FUNCTION_ARGS)
static PgChecksumMode mode
static const char * convert_aclright_to_string(int aclright)
#define ACL_ALL_RIGHTS_FUNCTION
Datum has_any_column_privilege_name(PG_FUNCTION_ARGS)
static Oid convert_language_name(text *languagename)
Datum has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS)
static Oid cached_member_role
Datum has_foreign_data_wrapper_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_database_privilege_name_id(PG_FUNCTION_ARGS)
AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode)
Datum has_server_privilege_name_name(PG_FUNCTION_ARGS)
Oid get_namespace_oid(const char *nspname, bool missing_ok)
#define ACLITEM_GET_GOPTIONS(item)
Datum has_function_privilege_name(PG_FUNCTION_ARGS)
int errhint(const char *fmt,...)
List * list_append_unique_oid(List *list, Oid datum)
Datum has_sequence_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_schema_privilege_name_name(PG_FUNCTION_ARGS)
#define PG_RETURN_ACL_P(x)
Datum has_sequence_privilege_name_name(PG_FUNCTION_ARGS)
static AttrNumber convert_column_name(Oid tableoid, text *column)
Datum aclcontains(PG_FUNCTION_ARGS)
Datum has_database_privilege_name(PG_FUNCTION_ARGS)
static Oid convert_schema_name(text *schemaname)
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
static AclResult pg_role_aclcheck(Oid role_oid, Oid roleid, AclMode mode)
TupleDesc CreateTemplateTupleDesc(int natts)
Datum aclexplode(PG_FUNCTION_ARGS)
Datum has_type_privilege_id(PG_FUNCTION_ARGS)
#define ACLITEM_ALL_GOPTION_BITS
#define SRF_IS_FIRSTCALL()
#define RangeVarGetRelid(relation, lockmode, missing_ok)
#define GetSysCacheOid1(cacheId, oidcol, key1)
char get_rel_relkind(Oid relid)
#define UInt64GetDatum(X)
Datum hash_aclitem_extended(PG_FUNCTION_ARGS)
#define DatumGetObjectId(X)
char * pstrdup(const char *in)
Datum pg_has_role_name(PG_FUNCTION_ARGS)
AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode)
static AclMode convert_function_priv_string(text *priv_type_text)
static Acl * allocacl(int n)
bool has_privs_of_role(Oid member, Oid role)
static Oid convert_foreign_data_wrapper_name(text *fdwname)
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Oid get_language_oid(const char *langname, bool missing_ok)
bool is_admin_of_role(Oid member, Oid role)
static bool has_rolinherit(Oid roleid)
Datum aclinsert(PG_FUNCTION_ARGS)
List * list_copy(const List *oldlist)
Oid get_role_oid_or_public(const char *rolname)
int errcode(int sqlerrcode)
Acl * acldefault(ObjectType objtype, Oid ownerId)
#define MemSet(start, val, len)
Datum has_function_privilege_id_name(PG_FUNCTION_ARGS)
Datum aclitemin(PG_FUNCTION_ARGS)
Datum idx(PG_FUNCTION_ARGS)
#define ACL_ALL_RIGHTS_TABLESPACE
static Oid convert_tablespace_name(text *tablespacename)
#define PG_GETARG_ACLITEM_P(n)
RangeVar * makeRangeVarFromNameList(List *names)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
#define DirectFunctionCall1(func, arg1)
#define PG_GETARG_BOOL(n)
Datum has_table_privilege_name_id(PG_FUNCTION_ARGS)
int pg_strcasecmp(const char *s1, const char *s2)
void initialize_acl(void)
bool IsReservedName(const char *name)
Datum pg_has_role_id(PG_FUNCTION_ARGS)
Datum has_server_privilege_name_id(PG_FUNCTION_ARGS)
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Datum has_sequence_privilege_name(PG_FUNCTION_ARGS)
Datum has_type_privilege_name_id(PG_FUNCTION_ARGS)
#define OidIsValid(objectId)
Datum has_server_privilege_id(PG_FUNCTION_ARGS)
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
#define SRF_PERCALL_SETUP()
Acl * make_empty_acl(void)
Datum has_function_privilege_name_id(PG_FUNCTION_ARGS)
Oid GetSessionUserId(void)
AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode)
Datum has_any_column_privilege_id_id(PG_FUNCTION_ARGS)
#define PG_RETURN_UINT32(x)
static AclMode convert_any_priv_string(text *priv_type_text, const priv_map *privileges)
Datum has_any_column_privilege_name_name(PG_FUNCTION_ARGS)
Datum pg_has_role_name_name(PG_FUNCTION_ARGS)
#define PG_GETARG_TEXT_PP(n)
Oid get_role_oid(const char *rolname, bool missing_ok)
Datum has_schema_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_foreign_data_wrapper_privilege_id(PG_FUNCTION_ARGS)
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
#define SRF_RETURN_NEXT(_funcctx, _result)
#define ACL_ALL_RIGHTS_LANGUAGE
Datum has_language_privilege_name(PG_FUNCTION_ARGS)
FormData_pg_authid * Form_pg_authid
static const FormData_pg_attribute a2
Oid get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok)
Datum pg_has_role_id_name(PG_FUNCTION_ARGS)
static List * roles_has_privs_of(Oid roleid)
#define SearchSysCacheExists1(cacheId, key1)
void pfree(void *pointer)
#define ACL_CREATE_TEMP_CHR
static int count_one_bits(AclMode mask)
Datum has_type_privilege_id_id(PG_FUNCTION_ARGS)
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
#define ObjectIdGetDatum(X)
static Oid cached_privs_role
Datum regprocedurein(PG_FUNCTION_ARGS)
Datum has_function_privilege_id(PG_FUNCTION_ARGS)
static const char * getid(const char *s, char *n)
Datum has_column_privilege_name_id_name(PG_FUNCTION_ARGS)
Datum has_tablespace_privilege_id_id(PG_FUNCTION_ARGS)
Datum has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS)
static List * roles_is_member_of(Oid roleid)
Datum pg_has_role_id_id(PG_FUNCTION_ARGS)
#define ACL_ALL_RIGHTS_SCHEMA
Datum has_table_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_column_privilege_id_attnum(PG_FUNCTION_ARGS)
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mode)
static AclMode convert_type_priv_string(text *priv_type_text)
#define ACL_REFERENCES_CHR
static AclMode convert_table_priv_string(text *priv_type_text)
Datum has_column_privilege_id_name_attnum(PG_FUNCTION_ARGS)
int errdetail(const char *fmt,...)
#define CStringGetDatum(X)
static AclMode convert_tablespace_priv_string(text *priv_type_text)
#define ACL_ALL_RIGHTS_TYPE
Datum has_tablespace_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_column_privilege_id_id_name(PG_FUNCTION_ARGS)
Datum has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS)
static Oid convert_database_name(text *databasename)
FormData_pg_attribute * Form_pg_attribute
Datum has_database_privilege_id(PG_FUNCTION_ARGS)
static AclMode convert_database_priv_string(text *priv_type_text)
#define SearchSysCacheList1(cacheId, key1)
#define ACLITEM_GET_RIGHTS(item)
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
void check_is_member_of_role(Oid member, Oid role)
static AclMode convert_language_priv_string(text *priv_type_text)
bool superuser_arg(Oid roleid)
Datum has_tablespace_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS)
MemoryContext TopMemoryContext
List * textToQualifiedNameList(text *textval)
char * get_rolespec_name(const RoleSpec *role)
Datum aclitemout(PG_FUNCTION_ARGS)
Datum has_schema_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_type_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_server_privilege_name(PG_FUNCTION_ARGS)
static Oid convert_server_name(text *servername)
Datum has_language_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_language_privilege_id(PG_FUNCTION_ARGS)
static AclMode convert_server_priv_string(text *priv_type_text)
Datum has_table_privilege_name_name(PG_FUNCTION_ARGS)
Acl * aclconcat(const Acl *left_acl, const Acl *right_acl)
Datum has_type_privilege_name(PG_FUNCTION_ARGS)
Datum has_server_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_schema_privilege_id(PG_FUNCTION_ARGS)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum has_database_privilege_id_name(PG_FUNCTION_ARGS)
#define ACLITEM_SET_RIGHTS(item, rights)
#define ReleaseSysCacheList(x)
Datum regtypein(PG_FUNCTION_ARGS)
void CacheRegisterSyscacheCallback(int cacheid, SyscacheCallbackFunction func, Datum arg)
#define ACL_GRANT_OPTION_FOR(privs)
void * palloc0(Size size)
Datum has_database_privilege_name_name(PG_FUNCTION_ARGS)
#define PG_RETURN_BOOL(x)
static List * cached_membership_roles
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
void ReleaseSysCache(HeapTuple tuple)
#define list_make1_oid(x1)
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
static const char * aclparse(const char *s, AclItem *aip)
Datum hash_aclitem(PG_FUNCTION_ARGS)
#define ACL_ALL_RIGHTS_SEQUENCE
FormData_pg_auth_members * Form_pg_auth_members
#define PG_GETARG_INT16(n)
Datum aclremove(PG_FUNCTION_ARGS)
Datum has_language_privilege_id_id(PG_FUNCTION_ARGS)
Datum has_sequence_privilege_id_id(PG_FUNCTION_ARGS)
static AclMode convert_priv_string(text *priv_type_text)
#define ACL_ALL_RIGHTS_STR
Oid get_database_oid(const char *dbname, bool missing_ok)
#define ereport(elevel,...)
#define ACL_ALL_RIGHTS_LARGEOBJECT
bool is_member_of_role(Oid member, Oid role)
Acl * aclcopy(const Acl *orig_acl)
#define ACL_OPTION_TO_PRIVS(privs)