mirror of
https://github.com/postgres/postgres.git
synced 2025-07-08 11:42:09 +03:00
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.
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user