diff options
author | Joe Conway <mail@joeconway.com> | 2009-08-03 21:11:40 +0000 |
---|---|---|
committer | Joe Conway <mail@joeconway.com> | 2009-08-03 21:11:40 +0000 |
commit | be6bca23b34b6e59f1deed1d6b44bb434dbe890e (patch) | |
tree | 23744d8f741e70d1ac47b4ba743346e53580b30d /src/backend/utils/adt/acl.c | |
parent | 7ffb14f9dbdbf0b735f9cb3b167fc848f3bd09ac (diff) | |
download | postgresql-be6bca23b34b6e59f1deed1d6b44bb434dbe890e.tar.gz postgresql-be6bca23b34b6e59f1deed1d6b44bb434dbe890e.zip |
Implement has_sequence_privilege()
Add family of functions that did not exist earlier,
mainly due to historical omission. Original patch by
Abhijit Menon-Sen, with review and modifications by
Joe Conway. catversion.h bumped.
Diffstat (limited to 'src/backend/utils/adt/acl.c')
-rw-r--r-- | src/backend/utils/adt/acl.c | 214 |
1 files changed, 213 insertions, 1 deletions
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 67c4ea36e36..83d93ad3483 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.148 2009/06/11 14:49:03 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.149 2009/08/03 21:11:39 joe Exp $ * *------------------------------------------------------------------------- */ @@ -20,6 +20,7 @@ #include "catalog/pg_authid.h" #include "catalog/pg_auth_members.h" #include "catalog/pg_type.h" +#include "catalog/pg_class.h" #include "commands/dbcommands.h" #include "commands/tablespace.h" #include "foreign/foreign.h" @@ -88,6 +89,7 @@ static AclMode convert_any_priv_string(text *priv_type_text, static Oid convert_table_name(text *tablename); static AclMode convert_table_priv_string(text *priv_type_text); +static AclMode convert_sequence_priv_string(text *priv_type_text); static AttrNumber convert_column_name(Oid tableoid, text *column); static AclMode convert_column_priv_string(text *priv_type_text); static Oid convert_database_name(text *databasename); @@ -1704,6 +1706,216 @@ convert_table_priv_string(text *priv_type_text) return convert_any_priv_string(priv_type_text, table_priv_map); } +/* + * has_sequence_privilege variants + * These are all named "has_sequence_privilege" at the SQL level. + * They take various combinations of relation name, relation OID, + * user name, user OID, or implicit user = current_user. + * + * The result is a boolean value: true if user has the indicated + * privilege, false if not. The variants that take a relation OID + * return NULL if the OID doesn't exist. + */ + +/* + * has_sequence_privilege_name_name + * Check user privileges on a sequence given + * name username, text sequencename, and text priv name. + */ +Datum +has_sequence_privilege_name_name(PG_FUNCTION_ARGS) +{ + Name rolename = PG_GETARG_NAME(0); + text *sequencename = PG_GETARG_TEXT_P(1); + text *priv_type_text = PG_GETARG_TEXT_P(2); + Oid roleid; + Oid sequenceoid; + AclMode mode; + AclResult aclresult; + + roleid = get_roleid_checked(NameStr(*rolename)); + mode = convert_sequence_priv_string(priv_type_text); + sequenceoid = convert_table_name(sequencename); + if (get_rel_relkind(sequenceoid) != RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a sequence", + text_to_cstring(sequencename)))); + + aclresult = pg_class_aclcheck(sequenceoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_sequence_privilege_name + * Check user privileges on a sequence given + * text sequencename and text priv name. + * current_user is assumed + */ +Datum +has_sequence_privilege_name(PG_FUNCTION_ARGS) +{ + text *sequencename = PG_GETARG_TEXT_P(0); + text *priv_type_text = PG_GETARG_TEXT_P(1); + Oid roleid; + Oid sequenceoid; + AclMode mode; + AclResult aclresult; + + roleid = GetUserId(); + mode = convert_sequence_priv_string(priv_type_text); + sequenceoid = convert_table_name(sequencename); + if (get_rel_relkind(sequenceoid) != RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a sequence", + text_to_cstring(sequencename)))); + + aclresult = pg_class_aclcheck(sequenceoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_sequence_privilege_name_id + * Check user privileges on a sequence given + * name usename, sequence oid, and text priv name. + */ +Datum +has_sequence_privilege_name_id(PG_FUNCTION_ARGS) +{ + Name username = PG_GETARG_NAME(0); + Oid sequenceoid = PG_GETARG_OID(1); + text *priv_type_text = PG_GETARG_TEXT_P(2); + Oid roleid; + AclMode mode; + AclResult aclresult; + char relkind; + + roleid = get_roleid_checked(NameStr(*username)); + mode = convert_sequence_priv_string(priv_type_text); + relkind = get_rel_relkind(sequenceoid); + if (relkind == '\0') + PG_RETURN_NULL(); + else if (relkind != RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a sequence", + get_rel_name(sequenceoid)))); + + aclresult = pg_class_aclcheck(sequenceoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_sequence_privilege_id + * Check user privileges on a sequence given + * sequence oid, and text priv name. + * current_user is assumed + */ +Datum +has_sequence_privilege_id(PG_FUNCTION_ARGS) +{ + Oid sequenceoid = PG_GETARG_OID(0); + text *priv_type_text = PG_GETARG_TEXT_P(1); + Oid roleid; + AclMode mode; + AclResult aclresult; + char relkind; + + roleid = GetUserId(); + mode = convert_sequence_priv_string(priv_type_text); + relkind = get_rel_relkind(sequenceoid); + if (relkind == '\0') + PG_RETURN_NULL(); + else if (relkind != RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a sequence", + get_rel_name(sequenceoid)))); + + aclresult = pg_class_aclcheck(sequenceoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_sequence_privilege_id_name + * Check user privileges on a sequence given + * roleid, text sequencename, and text priv name. + */ +Datum +has_sequence_privilege_id_name(PG_FUNCTION_ARGS) +{ + Oid roleid = PG_GETARG_OID(0); + text *sequencename = PG_GETARG_TEXT_P(1); + text *priv_type_text = PG_GETARG_TEXT_P(2); + Oid sequenceoid; + AclMode mode; + AclResult aclresult; + + mode = convert_sequence_priv_string(priv_type_text); + sequenceoid = convert_table_name(sequencename); + if (get_rel_relkind(sequenceoid) != RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a sequence", + text_to_cstring(sequencename)))); + + aclresult = pg_class_aclcheck(sequenceoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * has_sequence_privilege_id_id + * Check user privileges on a sequence given + * roleid, sequence oid, and text priv name. + */ +Datum +has_sequence_privilege_id_id(PG_FUNCTION_ARGS) +{ + Oid roleid = PG_GETARG_OID(0); + Oid sequenceoid = PG_GETARG_OID(1); + text *priv_type_text = PG_GETARG_TEXT_P(2); + AclMode mode; + AclResult aclresult; + char relkind; + + mode = convert_sequence_priv_string(priv_type_text); + relkind = get_rel_relkind(sequenceoid); + if (relkind == '\0') + PG_RETURN_NULL(); + else if (relkind != RELKIND_SEQUENCE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is not a sequence", + get_rel_name(sequenceoid)))); + + aclresult = pg_class_aclcheck(sequenceoid, roleid, mode); + + PG_RETURN_BOOL(aclresult == ACLCHECK_OK); +} + +/* + * convert_sequence_priv_string + * Convert text string to AclMode value. + */ +static AclMode +convert_sequence_priv_string(text *priv_type_text) +{ + static const priv_map sequence_priv_map[] = { + { "USAGE", ACL_USAGE }, + { "SELECT", ACL_SELECT }, + { "UPDATE", ACL_UPDATE }, + { NULL, 0 } + }; + + return convert_any_priv_string(priv_type_text, sequence_priv_map); +} + /* * has_any_column_privilege variants |