77 static const char *
getid(
const char *s,
char *n);
78 static void putid(
char *p,
const char *s);
137 bool in_quotes =
false;
141 while (isspace((
unsigned char) *s))
146 (isalnum((
unsigned char) *s) ||
157 in_quotes = !in_quotes;
167 (
errcode(ERRCODE_NAME_TOO_LONG),
168 errmsg(
"identifier too long"),
169 errdetail(
"Identifier must be less than %d characters.",
175 while (isspace((
unsigned char) *s))
191 for (src = s; *src; src++)
194 if (!isalnum((
unsigned char) *src) && *src !=
'_')
202 for (src = s; *src; src++)
249 if (strcmp(
name,
"group") != 0 && strcmp(
name,
"user") != 0)
251 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
252 errmsg(
"unrecognized key word: \"%s\"",
name),
253 errhint(
"ACL key word must be \"group\" or \"user\".")));
257 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
259 errhint(
"A name must follow the \"group\" or \"user\" key word.")));
264 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
265 errmsg(
"missing \"=\" sign")));
269 for (++s,
read = 0; isalpha((
unsigned char) *s) || *s ==
'*'; s++)
323 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
324 errmsg(
"invalid mode character: must be one of \"%s\"",
342 s =
getid(s + 1, name2);
343 if (name2[0] ==
'\0')
345 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
346 errmsg(
"a name must follow the \"/\" sign")));
353 (
errcode(ERRCODE_INVALID_GRANTOR),
354 errmsg(
"defaulting grantor to user ID %u",
355 BOOTSTRAP_SUPERUSERID)));
454 if (left_acl == NULL ||
ACL_NUM(left_acl) == 0)
456 if (right_acl == NULL ||
ACL_NUM(right_acl) == 0)
463 if (right_acl == NULL ||
ACL_NUM(right_acl) == 0)
468 result_acl =
aclcopy(left_acl);
473 for (
i = 0;
i < num;
i++, aip++)
480 result_acl = tmp_acl;
492 if (acl != NULL &&
ACL_NUM(acl) > 1)
507 if (left_acl == NULL ||
ACL_NUM(left_acl) == 0)
509 if (right_acl == NULL ||
ACL_NUM(right_acl) == 0)
516 if (right_acl == NULL ||
ACL_NUM(right_acl) == 0)
539 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
540 errmsg(
"ACL array contains wrong data type")));
543 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
544 errmsg(
"ACL arrays must be one-dimensional")));
547 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
548 errmsg(
"ACL arrays must not contain null values")));
567 while (isspace((
unsigned char) *s))
571 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
572 errmsg(
"extra garbage at the end of the ACL specification")));
594 out =
palloc(strlen(
"=/") +
655 return a1->ai_grantee ==
a2->ai_grantee &&
656 a1->ai_grantor ==
a2->ai_grantor;
669 if (
a1->ai_grantee >
a2->ai_grantee)
671 if (
a1->ai_grantee <
a2->ai_grantee)
673 if (
a1->ai_grantor >
a2->ai_grantor)
675 if (
a1->ai_grantor <
a2->ai_grantor)
677 if (
a1->ai_privs >
a2->ai_privs)
679 if (
a1->ai_privs <
a2->ai_privs)
694 result =
a1->ai_privs ==
a2->ai_privs &&
695 a1->ai_grantee ==
a2->ai_grantee &&
696 a1->ai_grantor ==
a2->ai_grantor;
811 elog(
ERROR,
"unrecognized objtype: %d", (
int) objtype);
908 elog(
ERROR,
"unrecognized objtype abbreviation: %c", objtypec);
963 for (dst = 0; dst < num; ++dst)
970 memcpy(new_acl, old_acl,
ACL_SIZE(old_acl));
980 memcpy(new_aip, old_aip, num *
sizeof(
AclItem));
1018 memmove(new_aip + dst,
1020 (num - dst - 1) *
sizeof(
AclItem));
1030 if ((old_goptions & ~new_goptions) != 0)
1034 (old_goptions & ~new_goptions),
1061 bool newpresent =
false;
1078 memcpy(new_aip, old_aip, num *
sizeof(
AclItem));
1079 for (dst = 0, dst_aip = new_aip; dst < num; dst++, dst_aip++)
1110 for (targ = 0, targ_aip = new_aip; targ < num; targ++, targ_aip++)
1116 for (src = targ + 1, src_aip = targ_aip + 1; src < num;
1131 new_aip[dst] = *targ_aip;
1179 memcpy(acl, old_acl,
ACL_SIZE(old_acl));
1185 for (
i = 0;
i < num;
i++)
1213 (
errcode(ERRCODE_INVALID_GRANT_OPERATION),
1214 errmsg(
"grant options cannot be granted back to your own grantor")));
1250 if (grantee == ownerId)
1254 still_has =
aclmask(acl, grantee, ownerId,
1264 for (
i = 0;
i < num;
i++)
1266 if (aip[
i].ai_grantor == grantee
1274 (
errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1275 errmsg(
"dependent privileges exist"),
1276 errhint(
"Use CASCADE to revoke them too.")));
1351 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1361 for (
i = 0;
i < num;
i++)
1369 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1382 for (
i = 0;
i < num;
i++)
1394 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1439 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1449 for (
i = 0;
i < num;
i++)
1456 if ((how ==
ACLMASK_ALL) ? (result == mask) : (result != 0))
1481 if (acl == NULL ||
ACL_NUM(acl) == 0)
1529 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1530 errmsg(
"aclinsert is no longer supported")));
1539 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1540 errmsg(
"aclremove is no longer supported")));
1557 for (
i = 0;
i < num; ++
i)
1629 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1630 errmsg(
"unrecognized privilege type: \"%s\"", priv_type)));
1654 for (chunk = priv_type; chunk; chunk = next_chunk)
1660 next_chunk = strchr(chunk,
',');
1662 *next_chunk++ =
'\0';
1665 while (*chunk && isspace((
unsigned char) *chunk))
1667 chunk_len = strlen(chunk);
1668 while (chunk_len > 0 && isspace((
unsigned char) chunk[chunk_len - 1]))
1670 chunk[chunk_len] =
'\0';
1673 for (this_priv = privileges; this_priv->
name; this_priv++)
1677 result |= this_priv->
value;
1681 if (!this_priv->
name)
1683 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1684 errmsg(
"unrecognized privilege type: \"%s\"", chunk)));
1708 return "REFERENCES";
1724 return "ALTER SYSTEM";
1726 elog(
ERROR,
"unrecognized aclright: %d", aclright);
1807 aidata = &aidat[
idx[0]];
1808 priv_bit = 1 <<
idx[1];
1822 MemSet(nulls, 0,
sizeof(nulls));
2021 static const priv_map table_priv_map[] = {
2037 {
"RULE WITH GRANT OPTION", 0},
2076 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2077 errmsg(
"\"%s\" is not a sequence",
2106 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2107 errmsg(
"\"%s\" is not a sequence",
2134 if (relkind ==
'\0')
2136 else if (relkind != RELKIND_SEQUENCE)
2138 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2139 errmsg(
"\"%s\" is not a sequence",
2166 if (relkind ==
'\0')
2168 else if (relkind != RELKIND_SEQUENCE)
2170 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2171 errmsg(
"\"%s\" is not a sequence",
2198 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2199 errmsg(
"\"%s\" is not a sequence",
2224 if (relkind ==
'\0')
2226 else if (relkind != RELKIND_SEQUENCE)
2228 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
2229 errmsg(
"\"%s\" is not a sequence",
2244 static const priv_map sequence_priv_map[] = {
2471 bool is_missing =
false;
2488 else if (is_missing)
2495 else if (is_missing)
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[] = {
3281 static const priv_map foreign_data_wrapper_priv_map[] = {
3468 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
3469 errmsg(
"function \"%s\" does not exist", funcname)));
3481 static const priv_map function_priv_map[] = {
3672 static const priv_map language_priv_map[] = {
3863 static const priv_map schema_priv_map[] = {
4056 static const priv_map server_priv_map[] = {
4247 static const priv_map tablespace_priv_map[] = {
4433 (
errcode(ERRCODE_UNDEFINED_OBJECT),
4446 static const priv_map type_priv_map[] = {
4535 static const priv_map parameter_priv_map[] = {
4713 static const priv_map role_priv_map[] = {
4805 bool result =
false;
4835 Oid admin_of,
bool *is_admin)
4840 List *new_cached_roles;
4881 foreach(l, roles_list)
4902 if (otherid == admin_of &&
4919 ROLE_PG_DATABASE_OWNER);
4926 new_cached_roles =
list_copy(roles_list);
5007 (
errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
5008 errmsg(
"must be member of role \"%s\"",
5045 bool result =
false;
5102 const Acl *acl,
Oid ownerId,
5118 *grantorId = ownerId;
5119 *grantOptions = needed_goptions;
5133 *grantorId = roleId;
5137 foreach(l, roles_list)
5144 if (otherprivs == needed_goptions)
5147 *grantorId = otherrole;
5148 *grantOptions = otherprivs;
5160 if (nnewrights > nrights)
5162 *grantorId = otherrole;
5163 *grantOptions = otherprivs;
5164 nrights = nnewrights;
5185 (
errcode(ERRCODE_UNDEFINED_OBJECT),
5197 if (strcmp(
rolname,
"public") == 0)
5233 (
errcode(ERRCODE_UNDEFINED_OBJECT),
5234 errmsg(
"role \"%s\" does not exist",
"public")));
5261 (
errcode(ERRCODE_UNDEFINED_OBJECT),
5280 (
errcode(ERRCODE_UNDEFINED_OBJECT),
5281 errmsg(
"role \"%s\" does not exist",
"public")));
5330 (
errcode(ERRCODE_RESERVED_NAME),
5331 errmsg(
"role name \"%s\" is reserved",
5336 (
errcode(ERRCODE_RESERVED_NAME),
5337 errmsg(
"role name \"%s\" is reserved",
Datum idx(PG_FUNCTION_ARGS)
Datum pg_has_role_id_id(PG_FUNCTION_ARGS)
Datum has_schema_privilege_id(PG_FUNCTION_ARGS)
Datum hash_aclitem(PG_FUNCTION_ARGS)
void initialize_acl(void)
Datum has_sequence_privilege_name(PG_FUNCTION_ARGS)
Datum has_table_privilege_id_id(PG_FUNCTION_ARGS)
Datum has_server_privilege_id(PG_FUNCTION_ARGS)
Acl * aclupdate(const Acl *old_acl, const AclItem *mod_aip, int modechg, Oid ownerId, DropBehavior behavior)
Datum has_tablespace_privilege_id_id(PG_FUNCTION_ARGS)
Datum has_column_privilege_id_id_attnum(PG_FUNCTION_ARGS)
Datum has_server_privilege_name_name(PG_FUNCTION_ARGS)
Datum aclinsert(PG_FUNCTION_ARGS)
static AclMode convert_function_priv_string(text *priv_type_text)
static const char * convert_aclright_to_string(int aclright)
bool is_admin_of_role(Oid member, Oid role)
Datum has_column_privilege_id_name(PG_FUNCTION_ARGS)
static bool aclitem_match(const AclItem *a1, const AclItem *a2)
Datum pg_has_role_name_name(PG_FUNCTION_ARGS)
Datum has_language_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_schema_privilege_name_name(PG_FUNCTION_ARGS)
Datum aclitem_eq(PG_FUNCTION_ARGS)
Datum has_tablespace_privilege_name_id(PG_FUNCTION_ARGS)
Datum makeaclitem(PG_FUNCTION_ARGS)
Datum has_table_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_server_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_column_privilege_name_id_attnum(PG_FUNCTION_ARGS)
Datum has_language_privilege_id_name(PG_FUNCTION_ARGS)
static int column_privilege_check(Oid tableoid, AttrNumber attnum, Oid roleid, AclMode mode)
static Oid convert_type_name(text *typename)
char * get_rolespec_name(const RoleSpec *role)
Datum aclexplode(PG_FUNCTION_ARGS)
static Oid convert_database_name(text *databasename)
Datum aclitemout(PG_FUNCTION_ARGS)
Oid get_role_oid_or_public(const char *rolname)
Datum has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_foreign_data_wrapper_privilege_id_id(PG_FUNCTION_ARGS)
bool aclequal(const Acl *left_acl, const Acl *right_acl)
Datum hash_aclitem_extended(PG_FUNCTION_ARGS)
static void check_acl(const Acl *acl)
Datum has_parameter_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_foreign_data_wrapper_privilege_id(PG_FUNCTION_ARGS)
Datum has_database_privilege_name(PG_FUNCTION_ARGS)
static uint32 cached_db_hash
Datum has_type_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_column_privilege_name_name_name(PG_FUNCTION_ARGS)
Datum pg_has_role_name(PG_FUNCTION_ARGS)
Datum has_sequence_privilege_id(PG_FUNCTION_ARGS)
static AclMode convert_type_priv_string(text *priv_type_text)
Datum has_tablespace_privilege_name(PG_FUNCTION_ARGS)
static AclMode convert_table_priv_string(text *priv_type_text)
static AclMode convert_server_priv_string(text *priv_type_text)
Datum has_table_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_foreign_data_wrapper_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_tablespace_privilege_id_name(PG_FUNCTION_ARGS)
static Acl * recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, Oid ownerId, DropBehavior behavior)
static void RoleMembershipCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
Datum has_database_privilege_name_id(PG_FUNCTION_ARGS)
static Oid convert_schema_name(text *schemaname)
Datum has_column_privilege_name_name(PG_FUNCTION_ARGS)
static void putid(char *p, const char *s)
Datum has_schema_privilege_id_name(PG_FUNCTION_ARGS)
static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, Oid ownerId)
static bool has_param_priv_byname(Oid roleid, const text *parameter, AclMode priv)
bool is_member_of_role(Oid member, Oid role)
Datum has_sequence_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_database_privilege_id_name(PG_FUNCTION_ARGS)
static Oid convert_foreign_data_wrapper_name(text *fdwname)
Datum has_language_privilege_id(PG_FUNCTION_ARGS)
static AclMode convert_database_priv_string(text *priv_type_text)
Datum has_foreign_data_wrapper_privilege_name(PG_FUNCTION_ARGS)
Datum has_column_privilege_name_attnum(PG_FUNCTION_ARGS)
Datum has_column_privilege_id_attnum(PG_FUNCTION_ARGS)
Datum has_type_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_any_column_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_server_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_language_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_foreign_data_wrapper_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_schema_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_function_privilege_name_name(PG_FUNCTION_ARGS)
void select_best_grantor(Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, Oid *grantorId, AclMode *grantOptions)
Datum has_any_column_privilege_name_name(PG_FUNCTION_ARGS)
bool is_member_of_role_nosuper(Oid member, Oid role)
Datum has_sequence_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_schema_privilege_name(PG_FUNCTION_ARGS)
Datum acldefault_sql(PG_FUNCTION_ARGS)
bool has_privs_of_role(Oid member, Oid role)
static Oid convert_language_name(text *languagename)
Datum has_language_privilege_id_id(PG_FUNCTION_ARGS)
static AclMode convert_any_priv_string(text *priv_type_text, const priv_map *privileges)
Datum has_database_privilege_id_id(PG_FUNCTION_ARGS)
Datum has_function_privilege_name(PG_FUNCTION_ARGS)
int aclmembers(const Acl *acl, Oid **roleids)
Datum has_language_privilege_name(PG_FUNCTION_ARGS)
Acl * aclconcat(const Acl *left_acl, const Acl *right_acl)
Acl * aclcopy(const Acl *orig_acl)
Datum has_server_privilege_name(PG_FUNCTION_ARGS)
Datum aclremove(PG_FUNCTION_ARGS)
static bool has_rolinherit(Oid roleid)
Datum has_function_privilege_id(PG_FUNCTION_ARGS)
void aclitemsort(Acl *acl)
Datum has_table_privilege_id(PG_FUNCTION_ARGS)
Datum has_function_privilege_id_id(PG_FUNCTION_ARGS)
AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
static Oid convert_server_name(text *servername)
Acl * acldefault(ObjectType objtype, Oid ownerId)
static Oid convert_tablespace_name(text *tablespacename)
Acl * make_empty_acl(void)
static const char * getid(const char *s, char *n)
Datum has_column_privilege_name_name_attnum(PG_FUNCTION_ARGS)
static AclMode convert_parameter_priv_string(text *priv_text)
static Oid convert_table_name(text *tablename)
Datum has_column_privilege_name_id_name(PG_FUNCTION_ARGS)
static int count_one_bits(AclMode mask)
static List * roles_is_member_of(Oid roleid, enum RoleRecurseType type, Oid admin_of, bool *is_admin)
static AclMode convert_tablespace_priv_string(text *priv_type_text)
static AclMode convert_language_priv_string(text *priv_type_text)
Datum aclitemin(PG_FUNCTION_ARGS)
static AclMode convert_sequence_priv_string(text *priv_type_text)
Datum pg_has_role_id(PG_FUNCTION_ARGS)
Datum has_parameter_privilege_id_name(PG_FUNCTION_ARGS)
Acl * aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId)
static Acl * allocacl(int n)
static AttrNumber convert_column_name(Oid tableoid, text *column)
static AclMode convert_role_priv_string(text *priv_type_text)
Oid get_role_oid(const char *rolname, bool missing_ok)
Datum has_tablespace_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_parameter_privilege_name(PG_FUNCTION_ARGS)
void check_is_member_of_role(Oid member, Oid role)
Datum has_any_column_privilege_name(PG_FUNCTION_ARGS)
Datum has_sequence_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_function_privilege_name_id(PG_FUNCTION_ARGS)
Datum has_type_privilege_id_id(PG_FUNCTION_ARGS)
Datum has_server_privilege_id_id(PG_FUNCTION_ARGS)
static AclResult pg_role_aclcheck(Oid role_oid, Oid roleid, AclMode mode)
Datum has_function_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_table_privilege_name(PG_FUNCTION_ARGS)
Datum has_type_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_column_privilege_id_name_attnum(PG_FUNCTION_ARGS)
void check_rolespec_name(const RoleSpec *role, const char *detail_msg)
Datum has_type_privilege_name(PG_FUNCTION_ARGS)
static AclMode convert_priv_string(text *priv_type_text)
static List * cached_roles[]
static AclMode aclmask_direct(const Acl *acl, Oid roleid, Oid ownerId, AclMode mask, AclMaskHow how)
Datum has_tablespace_privilege_id(PG_FUNCTION_ARGS)
Datum pg_has_role_name_id(PG_FUNCTION_ARGS)
Datum aclcontains(PG_FUNCTION_ARGS)
static Oid convert_function_name(text *functionname)
Datum has_column_privilege_id_name_name(PG_FUNCTION_ARGS)
Datum has_schema_privilege_id_id(PG_FUNCTION_ARGS)
Oid get_rolespec_oid(const RoleSpec *role, bool missing_ok)
Datum has_any_column_privilege_id_name(PG_FUNCTION_ARGS)
Datum has_database_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_column_privilege_id_id_name(PG_FUNCTION_ARGS)
static const char * aclparse(const char *s, AclItem *aip)
static AclMode convert_schema_priv_string(text *priv_type_text)
Datum has_table_privilege_name_name(PG_FUNCTION_ARGS)
Datum has_any_column_privilege_id_id(PG_FUNCTION_ARGS)
static AclMode convert_foreign_data_wrapper_priv_string(text *priv_type_text)
Datum has_database_privilege_id(PG_FUNCTION_ARGS)
static int aclitemComparator(const void *arg1, const void *arg2)
Datum has_type_privilege_id(PG_FUNCTION_ARGS)
Datum has_any_column_privilege_id(PG_FUNCTION_ARGS)
Datum pg_has_role_id_name(PG_FUNCTION_ARGS)
Acl * aclmerge(const Acl *left_acl, const Acl *right_acl, Oid ownerId)
Datum has_sequence_privilege_id_id(PG_FUNCTION_ARGS)
HeapTuple get_rolespec_tuple(const RoleSpec *role)
static AclMode convert_column_priv_string(text *priv_type_text)
#define PG_RETURN_ACLITEM_P(x)
#define ACL_ALL_RIGHTS_STR
#define ACL_REFERENCES_CHR
#define ACLITEM_ALL_GOPTION_BITS
#define PG_GETARG_ACLITEM_P(n)
#define ACL_ALL_RIGHTS_FOREIGN_SERVER
#define ACL_ALL_RIGHTS_TABLESPACE