Commit 4ab8e690 authored by Tom Lane's avatar Tom Lane

has_table_privilege spawns scions has_database_privilege, has_function_privilege,

has_language_privilege, has_schema_privilege to let SQL queries test
all the new privilege types in 7.3.  Also, add functions pg_table_is_visible,
pg_type_is_visible, pg_function_is_visible, pg_operator_is_visible,
pg_opclass_is_visible to test whether objects contained in schemas are
visible in the current search path.  Do some minor cleanup to centralize
accesses to pg_database, as well.
parent 65dc2e0d
......@@ -8,12 +8,10 @@
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/namespace.h"
#include "catalog/pg_database.h"
#include "commands/dbcommands.h"
#include "fmgr.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
static char *
......@@ -46,32 +44,16 @@ database_size(PG_FUNCTION_ARGS)
{
Name dbname = PG_GETARG_NAME(0);
HeapTuple tuple;
Relation relation;
ScanKeyData scanKey;
HeapScanDesc scan;
Oid dbid;
char *dbpath;
DIR *dirdesc;
struct dirent *direntry;
int64 totalsize;
relation = heap_openr(DatabaseRelationName, AccessShareLock);
ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,
F_NAMEEQ, NameGetDatum(dbname));
scan = heap_beginscan(relation, SnapshotNow, 1, &scanKey);
tuple = heap_getnext(scan, ForwardScanDirection);
if (!HeapTupleIsValid(tuple))
dbid = get_database_oid(NameStr(*dbname));
if (!OidIsValid(dbid))
elog(ERROR, "database %s does not exist", NameStr(*dbname));
dbid = HeapTupleGetOid(tuple);
if (dbid == InvalidOid)
elog(ERROR, "invalid database id");
heap_endscan(scan);
heap_close(relation, NoLock);
dbpath = GetDatabasePath(dbid);
dirdesc = opendir(dbpath);
......
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.109 2002/08/08 14:29:07 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.110 2002/08/09 16:45:13 tgl Exp $
PostgreSQL documentation
-->
......@@ -4925,57 +4925,11 @@ select current_setting('DateStyle');
<literal>false</literal> instead. It is the equivalent to the SQL
<command>SET</command> command. For example:
<programlisting>
SHOW show_query_stats;
show_query_stats
------------------
on
(1 row)
select set_config('show_query_stats','off','f');
set_config
------------
off
(1 row)
SHOW show_query_stats;
show_query_stats
------------------
off
(1 row)
select set_config('show_query_stats','on','t');
set_config
------------
on
(1 row)
SHOW show_query_stats;
show_query_stats
------------------
off
(1 row)
BEGIN;
BEGIN
select set_config('show_query_stats','on','t');
set_config
------------
on
(1 row)
SHOW show_query_stats;
show_query_stats
------------------
on
(1 row)
COMMIT;
COMMIT
SHOW show_query_stats;
show_query_stats
------------------
off
(1 row)
</programlisting>
</para>
......@@ -5002,6 +4956,66 @@ SHOW show_query_stats;
<entry><type>boolean</type></entry>
<entry>does current user have access to table</entry>
</row>
<row>
<entry><function>has_database_privilege</function>(<parameter>user</parameter>,
<parameter>database</parameter>,
<parameter>access</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>does user have access to database</entry>
</row>
<row>
<entry><function>has_database_privilege</function>(<parameter>database</parameter>,
<parameter>access</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>does current user have access to database</entry>
</row>
<row>
<entry><function>has_function_privilege</function>(<parameter>user</parameter>,
<parameter>function</parameter>,
<parameter>access</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>does user have access to function</entry>
</row>
<row>
<entry><function>has_function_privilege</function>(<parameter>function</parameter>,
<parameter>access</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>does current user have access to function</entry>
</row>
<row>
<entry><function>has_language_privilege</function>(<parameter>user</parameter>,
<parameter>language</parameter>,
<parameter>access</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>does user have access to language</entry>
</row>
<row>
<entry><function>has_language_privilege</function>(<parameter>language</parameter>,
<parameter>access</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>does current user have access to language</entry>
</row>
<row>
<entry><function>has_schema_privilege</function>(<parameter>user</parameter>,
<parameter>schema</parameter>,
<parameter>access</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>does user have access to schema</entry>
</row>
<row>
<entry><function>has_schema_privilege</function>(<parameter>schema</parameter>,
<parameter>access</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>does current user have access to schema</entry>
</row>
</tbody>
</tgroup>
</table>
......@@ -5009,9 +5023,21 @@ SHOW show_query_stats;
<indexterm zone="functions-misc">
<primary>has_table_privilege</primary>
</indexterm>
<indexterm zone="functions-misc">
<primary>has_database_privilege</primary>
</indexterm>
<indexterm zone="functions-misc">
<primary>has_function_privilege</primary>
</indexterm>
<indexterm zone="functions-misc">
<primary>has_language_privilege</primary>
</indexterm>
<indexterm zone="functions-misc">
<primary>has_schema_privilege</primary>
</indexterm>
<para>
<function>has_table_privilege</function> determines whether a user
<function>has_table_privilege</function> checks whether a user
can access a table in a particular way. The user can be
specified by name or by ID
(<classname>pg_user</classname>.<structfield>usesysid</structfield>), or if the argument is
......@@ -5032,6 +5058,140 @@ SELECT has_table_privilege('myschema.mytable', 'select');
</programlisting>
</para>
<para>
<function>has_database_privilege</function> checks whether a user
can access a database in a particular way. The possibilities for its
arguments are analogous to <function>has_table_privilege</function>.
The desired access type must evaluate to
<literal>CREATE</literal>,
<literal>TEMPORARY</literal>, or
<literal>TEMP</literal> (which is equivalent to
<literal>TEMPORARY</literal>).
</para>
<para>
<function>has_function_privilege</function> checks whether a user
can access a function in a particular way. The possibilities for its
arguments are analogous to <function>has_table_privilege</function>.
When specifying a function by a text string rather than by OID,
the allowed input is the same as for the <type>regprocedure</> datatype.
The desired access type must currently evaluate to
<literal>EXECUTE</literal>.
</para>
<para>
<function>has_language_privilege</function> checks whether a user
can access a procedural language in a particular way. The possibilities
for its arguments are analogous to <function>has_table_privilege</function>.
The desired access type must currently evaluate to
<literal>USAGE</literal>.
</para>
<para>
<function>has_schema_privilege</function> checks whether a user
can access a schema in a particular way. The possibilities for its
arguments are analogous to <function>has_table_privilege</function>.
The desired access type must evaluate to
<literal>CREATE</literal> or
<literal>USAGE</literal>.
</para>
<table>
<title>Schema Visibility Inquiry Functions</title>
<tgroup cols="3">
<thead>
<row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
</thead>
<tbody>
<row>
<entry><function>pg_table_is_visible</function>(<parameter>tableOID</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>is table visible in search path</entry>
</row>
<row>
<entry><function>pg_type_is_visible</function>(<parameter>typeOID</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>is type visible in search path</entry>
</row>
<row>
<entry><function>pg_function_is_visible</function>(<parameter>functionOID</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>is function visible in search path</entry>
</row>
<row>
<entry><function>pg_operator_is_visible</function>(<parameter>operatorOID</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>is operator visible in search path</entry>
</row>
<row>
<entry><function>pg_opclass_is_visible</function>(<parameter>opclassOID</parameter>)
</entry>
<entry><type>boolean</type></entry>
<entry>is operator class visible in search path</entry>
</row>
</tbody>
</tgroup>
</table>
<indexterm zone="functions-misc">
<primary>pg_table_is_visible</primary>
</indexterm>
<indexterm zone="functions-misc">
<primary>pg_type_is_visible</primary>
</indexterm>
<indexterm zone="functions-misc">
<primary>pg_function_is_visible</primary>
</indexterm>
<indexterm zone="functions-misc">
<primary>pg_operator_is_visible</primary>
</indexterm>
<indexterm zone="functions-misc">
<primary>pg_opclass_is_visible</primary>
</indexterm>
<para>
<function>pg_table_is_visible</function> checks whether a table
(or view, or any other kind of <structname>pg_class</> entry) is
<firstterm>visible</> in the current schema search path. A table
is said to be visible if its containing schema is in the search path
and no table of the same name appears earlier in the search path.
This is equivalent to the statement that the table can be referenced
by name without explicit schema qualification.
For example, to list the names of all visible tables:
<programlisting>
SELECT relname FROM pg_class WHERE pg_table_is_visible(oid);
</programlisting>
</para>
<para>
<function>pg_type_is_visible</function>,
<function>pg_function_is_visible</function>,
<function>pg_operator_is_visible</function>, and
<function>pg_opclass_is_visible</function> perform the same sort of
visibility check for types, functions, operators, and operator classes,
respectively. For functions and operators, an object in the search path
is visible if there is no object of the same name <emphasis>and argument
datatype(s)</> earlier in the path. For operator classes,
both name and associated index access method are considered.
</para>
<para>
All these functions require object OIDs to identify the object to be
checked. If you want to test an object by name, it is convenient to use
the OID alias types (<type>regclass</>, <type>regtype</>,
<type>regprocedure</>, or <type>regoperator</>), for example
<programlisting>
SELECT pg_type_is_visible('myschema.widget'::regtype);
</programlisting>
Note that it would not make much sense to test an unqualified name in
this way --- if the name can be recognized at all, it must be visible.
</para>
<table>
<title>Catalog Information Functions</title>
<tgroup cols="3">
......
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.29 2002/08/08 01:44:30 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.30 2002/08/09 16:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -137,6 +137,13 @@ static void RemoveTempRelations(Oid tempNamespaceId);
static void RemoveTempRelationsCallback(void);
static void NamespaceCallback(Datum arg, Oid relid);
/* These don't really need to appear in any header file */
Datum pg_table_is_visible(PG_FUNCTION_ARGS);
Datum pg_type_is_visible(PG_FUNCTION_ARGS);
Datum pg_function_is_visible(PG_FUNCTION_ARGS);
Datum pg_operator_is_visible(PG_FUNCTION_ARGS);
Datum pg_opclass_is_visible(PG_FUNCTION_ARGS);
/*
* RangeVarGetRelid
......@@ -1747,3 +1754,47 @@ fetch_search_path(bool includeImplicit)
return result;
}
/*
* Export the FooIsVisible functions as SQL-callable functions.
*/
Datum
pg_table_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0);
PG_RETURN_BOOL(RelationIsVisible(oid));
}
Datum
pg_type_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0);
PG_RETURN_BOOL(TypeIsVisible(oid));
}
Datum
pg_function_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0);
PG_RETURN_BOOL(FunctionIsVisible(oid));
}
Datum
pg_operator_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0);
PG_RETURN_BOOL(OperatorIsVisible(oid));
}
Datum
pg_opclass_is_visible(PG_FUNCTION_ARGS)
{
Oid oid = PG_GETARG_OID(0);
PG_RETURN_BOOL(OpclassIsVisible(oid));
}
......@@ -7,7 +7,7 @@
* Copyright (c) 1996-2001, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.55 2002/08/05 03:29:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.56 2002/08/09 16:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -20,12 +20,12 @@
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_database.h"
#include "catalog/pg_description.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_rewrite.h"
#include "catalog/pg_trigger.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
......@@ -398,34 +398,16 @@ static void
CommentDatabase(List *qualname, char *comment)
{
char *database;
Relation pg_database;
ScanKeyData entry;
HeapScanDesc scan;
HeapTuple dbtuple;
Oid oid;
if (length(qualname) != 1)
elog(ERROR, "CommentDatabase: database name may not be qualified");
database = strVal(lfirst(qualname));
/* Only allow comments on the current database */
if (strcmp(database, DatabaseName) != 0)
elog(ERROR, "Database comments may only be applied to the current database");
/* First find the tuple in pg_database for the database */
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
ScanKeyEntryInitialize(&entry, 0, Anum_pg_database_datname,
F_NAMEEQ, CStringGetDatum(database));
scan = heap_beginscan(pg_database, SnapshotNow, 1, &entry);
dbtuple = heap_getnext(scan, ForwardScanDirection);
/* Validate database exists, and fetch the db oid */
if (!HeapTupleIsValid(dbtuple))
/* First get the database OID */
oid = get_database_oid(database);
if (!OidIsValid(oid))
elog(ERROR, "database \"%s\" does not exist", database);
AssertTupleDescHasOid(pg_database->rd_att);
oid = HeapTupleGetOid(dbtuple);
/* Allow if the user matches the database dba or is a superuser */
......@@ -433,14 +415,12 @@ CommentDatabase(List *qualname, char *comment)
elog(ERROR, "you are not permitted to comment on database \"%s\"",
database);
/* Create the comment with the pg_database oid */
/* Only allow comments on the current database */
if (oid != MyDatabaseId)
elog(ERROR, "Database comments may only be applied to the current database");
/* Create the comment with the pg_database oid */
CreateComments(oid, RelOid_pg_database, 0, comment);
/* Complete the scan and close any opened relations */
heap_endscan(scan);
heap_close(pg_database, AccessShareLock);
}
/*
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.98 2002/08/05 03:29:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.99 2002/08/09 16:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -746,3 +746,78 @@ remove_dbdirs(const char *nominal_loc, const char *alt_loc)
return success;
}
/*
* get_database_oid - given a database name, look up the OID
*
* Returns InvalidOid if database name not found.
*
* This is not actually used in this file, but is exported for use elsewhere.
*/
Oid
get_database_oid(const char *dbname)
{
Relation pg_database;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple dbtuple;
Oid oid;
/* There's no syscache for pg_database, so must look the hard way */
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
ScanKeyEntryInitialize(&entry[0], 0x0,
Anum_pg_database_datname, F_NAMEEQ,
CStringGetDatum(dbname));
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
dbtuple = heap_getnext(scan, ForwardScanDirection);
/* We assume that there can be at most one matching tuple */
if (HeapTupleIsValid(dbtuple))
oid = HeapTupleGetOid(dbtuple);
else
oid = InvalidOid;
heap_endscan(scan);
heap_close(pg_database, AccessShareLock);
return oid;
}
/*
* get_database_owner - given a database OID, fetch the owner's usesysid.
*
* Errors out if database not found.
*
* This is not actually used in this file, but is exported for use elsewhere.
*/
Oid
get_database_owner(Oid dbid)
{
Relation pg_database;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple dbtuple;
int32 dba;
/* There's no syscache for pg_database, so must look the hard way */
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
ScanKeyEntryInitialize(&entry[0], 0x0,
ObjectIdAttributeNumber, F_OIDEQ,
ObjectIdGetDatum(dbid));
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
dbtuple = heap_getnext(scan, ForwardScanDirection);
if (!HeapTupleIsValid(dbtuple))
elog(ERROR, "database %u does not exist", dbid);
dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba;
heap_endscan(scan);
heap_close(pg_database, AccessShareLock);
/* XXX some confusion about whether userids are OID or int4 ... */
return (Oid) dba;
}
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.74 2002/06/20 20:29:36 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.75 2002/08/09 16:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -18,6 +18,7 @@
#include "catalog/namespace.h"
#include "catalog/pg_shadow.h"
#include "commands/dbcommands.h"
#include "miscadmin.h"
#include "utils/acl.h"
#include "utils/builtins.h"
......@@ -34,8 +35,16 @@ static const char *aclparse(const char *s, AclItem *aip, unsigned *modechg);
static bool aclitemeq(const AclItem *a1, const AclItem *a2);
static bool aclitemgt(const AclItem *a1, const AclItem *a2);
static AclMode convert_priv_string(text *priv_type_text);
static Oid convert_rel_name(text *relname);
static Oid convert_table_name(text *tablename);
static AclMode convert_table_priv_string(text *priv_type_text);
static Oid convert_database_name(text *databasename);
static AclMode convert_database_priv_string(text *priv_type_text);
static Oid convert_function_name(text *functionname);
static AclMode convert_function_priv_string(text *priv_type_text);
static Oid convert_language_name(text *languagename);
static AclMode convert_language_priv_string(text *priv_type_text);
static Oid convert_schema_name(text *schemaname);
static AclMode convert_schema_priv_string(text *priv_type_text);
/*
......@@ -646,266 +655,179 @@ aclcontains(PG_FUNCTION_ARGS)
/*
* has_table_privilege_name_name
* Check user privileges on a relation given
* name username, text relname, and text priv name.
* has_table_privilege variants
* These are all named "has_table_privilege" at the SQL level.
* They take various combinations of relation name, relation OID,
* user name, user sysid, or implicit user = current_user.
*
* RETURNS
* a boolean value
* 't' indicating user has the privilege
* 'f' indicating user does not have the privilege
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
*/
/*
* has_table_privilege_name_name
* Check user privileges on a table given
* name username, text tablename, and text priv name.
*/
Datum
has_table_privilege_name_name(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
text *relname = PG_GETARG_TEXT_P(1);
text *tablename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
Oid reloid;
Oid tableoid;
AclMode mode;
AclResult aclresult;
/*
* Lookup userid based on username
*/
usesysid = get_usesysid(NameStr(*username));
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
/*
* Lookup rel OID based on relname
*/
reloid = convert_rel_name(relname);
/*
* Convert priv_type_text to an AclMode
*/
mode = convert_priv_string(priv_type_text);
/*
* Check for the privilege
*/
aclresult = pg_class_aclcheck(reloid, usesysid, mode);
aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_table_privilege_name
* Check user privileges on a relation given
* text relname and text priv name.
* Check user privileges on a table given
* text tablename and text priv name.
* current_user is assumed
*
* RETURNS
* a boolean value
* 't' indicating user has the privilege
* 'f' indicating user does not have the privilege
*/
Datum
has_table_privilege_name(PG_FUNCTION_ARGS)
{
text *relname = PG_GETARG_TEXT_P(0);
text *tablename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
Oid reloid;
Oid tableoid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
/*
* Lookup rel OID based on relname
*/
reloid = convert_rel_name(relname);
/*
* Convert priv_type_text to an AclMode
*/
mode = convert_priv_string(priv_type_text);
/*
* Check for the privilege
*/
aclresult = pg_class_aclcheck(reloid, usesysid, mode);
aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_table_privilege_name_id
* Check user privileges on a relation given
* name usename, rel oid, and text priv name.
*
* RETURNS
* a boolean value
* 't' indicating user has the privilege
* 'f' indicating user does not have the privilege
* Check user privileges on a table given
* name usename, table oid, and text priv name.
*/
Datum
has_table_privilege_name_id(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
Oid reloid = PG_GETARG_OID(1);
Oid tableoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
AclMode mode;
AclResult aclresult;
/*
* Lookup userid based on username
*/
usesysid = get_usesysid(NameStr(*username));
mode = convert_table_priv_string(priv_type_text);
/*
* Convert priv_type_text to an AclMode
*/
mode = convert_priv_string(priv_type_text);
/*
* Check for the privilege
*/
aclresult = pg_class_aclcheck(reloid, usesysid, mode);
aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_table_privilege_id
* Check user privileges on a relation given
* rel oid, and text priv name.
* Check user privileges on a table given
* table oid, and text priv name.
* current_user is assumed
*
* RETURNS
* a boolean value
* 't' indicating user has the privilege
* 'f' indicating user does not have the privilege
*/
Datum
has_table_privilege_id(PG_FUNCTION_ARGS)
{
Oid reloid = PG_GETARG_OID(0);
Oid tableoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
mode = convert_table_priv_string(priv_type_text);
/*
* Convert priv_type_text to an AclMode
*/
mode = convert_priv_string(priv_type_text);
/*
* Check for the privilege
*/
aclresult = pg_class_aclcheck(reloid, usesysid, mode);
aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_table_privilege_id_name
* Check user privileges on a relation given
* usesysid, text relname, and priv name.
*
* RETURNS
* a boolean value
* 't' indicating user has the privilege
* 'f' indicating user does not have the privilege
* Check user privileges on a table given
* usesysid, text tablename, and text priv name.
*/
Datum
has_table_privilege_id_name(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
text *relname = PG_GETARG_TEXT_P(1);
text *tablename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid reloid;
Oid tableoid;
AclMode mode;
AclResult aclresult;
/*
* Lookup rel OID based on relname
*/
reloid = convert_rel_name(relname);
/*
* Convert priv_type_text to an AclMode
*/
mode = convert_priv_string(priv_type_text);
tableoid = convert_table_name(tablename);
mode = convert_table_priv_string(priv_type_text);
/*
* Check for the privilege
*/
aclresult = pg_class_aclcheck(reloid, usesysid, mode);
aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_table_privilege_id_id
* Check user privileges on a relation given
* usesysid, rel oid, and priv name.
*
* RETURNS
* a boolean value
* 't' indicating user has the privilege
* 'f' indicating user does not have the privilege
* Check user privileges on a table given
* usesysid, table oid, and text priv name.
*/
Datum
has_table_privilege_id_id(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
Oid reloid = PG_GETARG_OID(1);
Oid tableoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
AclResult aclresult;
/*
* Convert priv_type_text to an AclMode
*/
mode = convert_priv_string(priv_type_text);
mode = convert_table_priv_string(priv_type_text);
/*
* Check for the privilege
*/
aclresult = pg_class_aclcheck(reloid, usesysid, mode);
aclresult = pg_class_aclcheck(tableoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* Internal functions.
* Support routines for has_table_privilege family.
*/
/*
* Given a relation name expressed as a string, look it up and return Oid
* Given a table name expressed as a string, look it up and return Oid
*/
static Oid
convert_rel_name(text *relname)
convert_table_name(text *tablename)
{
RangeVar *relrv;
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,
relrv = makeRangeVarFromNameList(textToQualifiedNameList(tablename,
"has_table_privilege"));
return RangeVarGetRelid(relrv, false);
}
/*
* convert_priv_string
* Internal function.
* Return mode from priv_type string
*
* RETURNS
* AclMode
* convert_table_priv_string
* Convert text string to AclMode value.
*/
static AclMode
convert_priv_string(text *priv_type_text)
convert_table_priv_string(text *priv_type_text)
{
char *priv_type;
......@@ -936,10 +858,810 @@ convert_priv_string(text *priv_type_text)
if (strcasecmp(priv_type, "TRIGGER") == 0)
return ACL_TRIGGER;
elog(ERROR, "has_table_privilege: invalid privilege type %s", priv_type);
elog(ERROR, "has_table_privilege: invalid privilege type %s",
priv_type);
return ACL_NO_RIGHTS; /* keep compiler quiet */
}
/*
* has_database_privilege variants
* These are all named "has_database_privilege" at the SQL level.
* They take various combinations of database name, database OID,
* user name, user sysid, or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
*/
/*
* has_database_privilege_name_name
* Check user privileges on a database given
* name username, text databasename, and text priv name.
*/
Datum
has_database_privilege_name_name(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
text *databasename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
Oid databaseoid;
AclMode mode;
AclResult aclresult;
usesysid = get_usesysid(NameStr(*username));
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_database_privilege_name
* Check user privileges on a database given
* text databasename and text priv name.
* current_user is assumed
*/
Datum
has_database_privilege_name(PG_FUNCTION_ARGS)
{
text *databasename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
Oid databaseoid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_database_privilege_name_id
* Check user privileges on a database given
* name usename, database oid, and text priv name.
*/
Datum
has_database_privilege_name_id(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
Oid databaseoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = get_usesysid(NameStr(*username));
mode = convert_database_priv_string(priv_type_text);
aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_database_privilege_id
* Check user privileges on a database given
* database oid, and text priv name.
* current_user is assumed
*/
Datum
has_database_privilege_id(PG_FUNCTION_ARGS)
{
Oid databaseoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
mode = convert_database_priv_string(priv_type_text);
aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_database_privilege_id_name
* Check user privileges on a database given
* usesysid, text databasename, and text priv name.
*/
Datum
has_database_privilege_id_name(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
text *databasename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid databaseoid;
AclMode mode;
AclResult aclresult;
databaseoid = convert_database_name(databasename);
mode = convert_database_priv_string(priv_type_text);
aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_database_privilege_id_id
* Check user privileges on a database given
* usesysid, database oid, and text priv name.
*/
Datum
has_database_privilege_id_id(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
Oid databaseoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
AclResult aclresult;
mode = convert_database_priv_string(priv_type_text);
aclresult = pg_database_aclcheck(databaseoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* Support routines for has_database_privilege family.
*/
/*
* Given a database name expressed as a string, look it up and return Oid
*/
static Oid
convert_database_name(text *databasename)
{
char *dbname;
Oid oid;
dbname = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(databasename)));
oid = get_database_oid(dbname);
if (!OidIsValid(oid))
elog(ERROR, "database \"%s\" does not exist", dbname);
return oid;
}
/*
* convert_database_priv_string
* Convert text string to AclMode value.
*/
static AclMode
convert_database_priv_string(text *priv_type_text)
{
char *priv_type;
priv_type = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(priv_type_text)));
/*
* We should never get here, but stop the compiler from complaining
* Return mode from priv_type string
*/
if (strcasecmp(priv_type, "CREATE") == 0)
return ACL_CREATE;
if (strcasecmp(priv_type, "TEMPORARY") == 0)
return ACL_CREATE_TEMP;
if (strcasecmp(priv_type, "TEMP") == 0)
return ACL_CREATE_TEMP;
elog(ERROR, "has_database_privilege: invalid privilege type %s",
priv_type);
return ACL_NO_RIGHTS; /* keep compiler quiet */
}
/*
* has_function_privilege variants
* These are all named "has_function_privilege" at the SQL level.
* They take various combinations of function name, function OID,
* user name, user sysid, or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
*/
/*
* has_function_privilege_name_name
* Check user privileges on a function given
* name username, text functionname, and text priv name.
*/
Datum
has_function_privilege_name_name(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
text *functionname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
Oid functionoid;
AclMode mode;
AclResult aclresult;
usesysid = get_usesysid(NameStr(*username));
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_function_privilege_name
* Check user privileges on a function given
* text functionname and text priv name.
* current_user is assumed
*/
Datum
has_function_privilege_name(PG_FUNCTION_ARGS)
{
text *functionname = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
Oid functionoid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_function_privilege_name_id
* Check user privileges on a function given
* name usename, function oid, and text priv name.
*/
Datum
has_function_privilege_name_id(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
Oid functionoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = get_usesysid(NameStr(*username));
mode = convert_function_priv_string(priv_type_text);
aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_function_privilege_id
* Check user privileges on a function given
* function oid, and text priv name.
* current_user is assumed
*/
Datum
has_function_privilege_id(PG_FUNCTION_ARGS)
{
Oid functionoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
mode = convert_function_priv_string(priv_type_text);
aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_function_privilege_id_name
* Check user privileges on a function given
* usesysid, text functionname, and text priv name.
*/
return ACL_NO_RIGHTS;
Datum
has_function_privilege_id_name(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
text *functionname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid functionoid;
AclMode mode;
AclResult aclresult;
functionoid = convert_function_name(functionname);
mode = convert_function_priv_string(priv_type_text);
aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_function_privilege_id_id
* Check user privileges on a function given
* usesysid, function oid, and text priv name.
*/
Datum
has_function_privilege_id_id(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
Oid functionoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
AclResult aclresult;
mode = convert_function_priv_string(priv_type_text);
aclresult = pg_proc_aclcheck(functionoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* Support routines for has_function_privilege family.
*/
/*
* Given a function name expressed as a string, look it up and return Oid
*/
static Oid
convert_function_name(text *functionname)
{
char *funcname;
Oid oid;
funcname = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(functionname)));
oid = DatumGetObjectId(DirectFunctionCall1(regprocedurein,
CStringGetDatum(funcname)));
if (!OidIsValid(oid))
elog(ERROR, "function \"%s\" does not exist", funcname);
return oid;
}
/*
* convert_function_priv_string
* Convert text string to AclMode value.
*/
static AclMode
convert_function_priv_string(text *priv_type_text)
{
char *priv_type;
priv_type = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(priv_type_text)));
/*
* Return mode from priv_type string
*/
if (strcasecmp(priv_type, "EXECUTE") == 0)
return ACL_EXECUTE;
elog(ERROR, "has_function_privilege: invalid privilege type %s",
priv_type);
return ACL_NO_RIGHTS; /* keep compiler quiet */
}
/*
* has_language_privilege variants
* These are all named "has_language_privilege" at the SQL level.
* They take various combinations of language name, language OID,
* user name, user sysid, or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
*/
/*
* has_language_privilege_name_name
* Check user privileges on a language given
* name username, text languagename, and text priv name.
*/
Datum
has_language_privilege_name_name(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
text *languagename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
Oid languageoid;
AclMode mode;
AclResult aclresult;
usesysid = get_usesysid(NameStr(*username));
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_language_privilege_name
* Check user privileges on a language given
* text languagename and text priv name.
* current_user is assumed
*/
Datum
has_language_privilege_name(PG_FUNCTION_ARGS)
{
text *languagename = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
Oid languageoid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_language_privilege_name_id
* Check user privileges on a language given
* name usename, language oid, and text priv name.
*/
Datum
has_language_privilege_name_id(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
Oid languageoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = get_usesysid(NameStr(*username));
mode = convert_language_priv_string(priv_type_text);
aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_language_privilege_id
* Check user privileges on a language given
* language oid, and text priv name.
* current_user is assumed
*/
Datum
has_language_privilege_id(PG_FUNCTION_ARGS)
{
Oid languageoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
mode = convert_language_priv_string(priv_type_text);
aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_language_privilege_id_name
* Check user privileges on a language given
* usesysid, text languagename, and text priv name.
*/
Datum
has_language_privilege_id_name(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
text *languagename = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid languageoid;
AclMode mode;
AclResult aclresult;
languageoid = convert_language_name(languagename);
mode = convert_language_priv_string(priv_type_text);
aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_language_privilege_id_id
* Check user privileges on a language given
* usesysid, language oid, and text priv name.
*/
Datum
has_language_privilege_id_id(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
Oid languageoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
AclResult aclresult;
mode = convert_language_priv_string(priv_type_text);
aclresult = pg_language_aclcheck(languageoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* Support routines for has_language_privilege family.
*/
/*
* Given a language name expressed as a string, look it up and return Oid
*/
static Oid
convert_language_name(text *languagename)
{
char *langname;
Oid oid;
langname = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(languagename)));
oid = GetSysCacheOid(LANGNAME,
CStringGetDatum(langname),
0, 0, 0);
if (!OidIsValid(oid))
elog(ERROR, "language \"%s\" does not exist", langname);
return oid;
}
/*
* convert_language_priv_string
* Convert text string to AclMode value.
*/
static AclMode
convert_language_priv_string(text *priv_type_text)
{
char *priv_type;
priv_type = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(priv_type_text)));
/*
* Return mode from priv_type string
*/
if (strcasecmp(priv_type, "USAGE") == 0)
return ACL_USAGE;
elog(ERROR, "has_language_privilege: invalid privilege type %s",
priv_type);
return ACL_NO_RIGHTS; /* keep compiler quiet */
}
/*
* has_schema_privilege variants
* These are all named "has_schema_privilege" at the SQL level.
* They take various combinations of schema name, schema OID,
* user name, user sysid, or implicit user = current_user.
*
* The result is a boolean value: true if user has the indicated
* privilege, false if not.
*/
/*
* has_schema_privilege_name_name
* Check user privileges on a schema given
* name username, text schemaname, and text priv name.
*/
Datum
has_schema_privilege_name_name(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
text *schemaname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
Oid schemaoid;
AclMode mode;
AclResult aclresult;
usesysid = get_usesysid(NameStr(*username));
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_schema_privilege_name
* Check user privileges on a schema given
* text schemaname and text priv name.
* current_user is assumed
*/
Datum
has_schema_privilege_name(PG_FUNCTION_ARGS)
{
text *schemaname = PG_GETARG_TEXT_P(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
Oid schemaoid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_schema_privilege_name_id
* Check user privileges on a schema given
* name usename, schema oid, and text priv name.
*/
Datum
has_schema_privilege_name_id(PG_FUNCTION_ARGS)
{
Name username = PG_GETARG_NAME(0);
Oid schemaoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = get_usesysid(NameStr(*username));
mode = convert_schema_priv_string(priv_type_text);
aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_schema_privilege_id
* Check user privileges on a schema given
* schema oid, and text priv name.
* current_user is assumed
*/
Datum
has_schema_privilege_id(PG_FUNCTION_ARGS)
{
Oid schemaoid = PG_GETARG_OID(0);
text *priv_type_text = PG_GETARG_TEXT_P(1);
int32 usesysid;
AclMode mode;
AclResult aclresult;
usesysid = GetUserId();
mode = convert_schema_priv_string(priv_type_text);
aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_schema_privilege_id_name
* Check user privileges on a schema given
* usesysid, text schemaname, and text priv name.
*/
Datum
has_schema_privilege_id_name(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
text *schemaname = PG_GETARG_TEXT_P(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
Oid schemaoid;
AclMode mode;
AclResult aclresult;
schemaoid = convert_schema_name(schemaname);
mode = convert_schema_priv_string(priv_type_text);
aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* has_schema_privilege_id_id
* Check user privileges on a schema given
* usesysid, schema oid, and text priv name.
*/
Datum
has_schema_privilege_id_id(PG_FUNCTION_ARGS)
{
int32 usesysid = PG_GETARG_INT32(0);
Oid schemaoid = PG_GETARG_OID(1);
text *priv_type_text = PG_GETARG_TEXT_P(2);
AclMode mode;
AclResult aclresult;
mode = convert_schema_priv_string(priv_type_text);
aclresult = pg_namespace_aclcheck(schemaoid, usesysid, mode);
PG_RETURN_BOOL(aclresult == ACLCHECK_OK);
}
/*
* Support routines for has_schema_privilege family.
*/
/*
* Given a schema name expressed as a string, look it up and return Oid
*/
static Oid
convert_schema_name(text *schemaname)
{
char *nspname;
Oid oid;
nspname = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(schemaname)));
oid = GetSysCacheOid(NAMESPACENAME,
CStringGetDatum(nspname),
0, 0, 0);
if (!OidIsValid(oid))
elog(ERROR, "schema \"%s\" does not exist", nspname);
return oid;
}
/*
* convert_schema_priv_string
* Convert text string to AclMode value.
*/
static AclMode
convert_schema_priv_string(text *priv_type_text)
{
char *priv_type;
priv_type = DatumGetCString(DirectFunctionCall1(textout,
PointerGetDatum(priv_type_text)));
/*
* Return mode from priv_type string
*/
if (strcasecmp(priv_type, "CREATE") == 0)
return ACL_CREATE;
if (strcasecmp(priv_type, "USAGE") == 0)
return ACL_USAGE;
elog(ERROR, "has_schema_privilege: invalid privilege type %s",
priv_type);
return ACL_NO_RIGHTS; /* keep compiler quiet */
}
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.50 2002/08/05 03:29:17 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.51 2002/08/09 16:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -25,6 +25,7 @@
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "utils/fcache.h"
#include "utils/fmgroids.h"
#include "utils/sets.h"
#include "utils/syscache.h"
......@@ -58,7 +59,7 @@ SetDefine(char *querystr, Oid elemType)
true, /* returnsSet */
elemType, /* returnType */
SQLlanguageId, /* language */
SQLvalidatorId,
F_FMGR_SQL_VALIDATOR,
querystr, /* prosrc */
fileName, /* probin */
false, /* not aggregate */
......
......@@ -10,19 +10,17 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.23 2002/06/20 20:29:40 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.24 2002/08/09 16:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_database.h"
#include "catalog/pg_shadow.h"
#include "commands/dbcommands.h"
#include "utils/syscache.h"
#include "miscadmin.h"
#include "utils/fmgroids.h"
/*
......@@ -69,25 +67,9 @@ superuser_arg(Oid userid)
bool
is_dbadmin(Oid dbid)
{
Relation pg_database;
ScanKeyData entry[1];
HeapScanDesc scan;
HeapTuple dbtuple;
int32 dba;
Oid dba;
/* There's no syscache for pg_database, so must look the hard way */
pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
ScanKeyEntryInitialize(&entry[0], 0x0,
ObjectIdAttributeNumber, F_OIDEQ,
ObjectIdGetDatum(dbid));
scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
dbtuple = heap_getnext(scan, ForwardScanDirection);
if (!HeapTupleIsValid(dbtuple))
elog(ERROR, "database %u does not exist", dbid);
dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba;
heap_endscan(scan);
heap_close(pg_database, AccessShareLock);
dba = get_database_owner(dbid);
/* XXX some confusion about whether userids are OID or int4 ... */
return (GetUserId() == (Oid) dba);
return (GetUserId() == dba);
}
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: catversion.h,v 1.146 2002/08/06 05:40:45 ishii Exp $
* $Id: catversion.h,v 1.147 2002/08/09 16:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 200208061
#define CATALOG_VERSION_NO 200208091
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pg_proc.h,v 1.252 2002/08/06 05:40:45 ishii Exp $
* $Id: pg_proc.h,v 1.253 2002/08/09 16:45:15 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
......@@ -2675,15 +2675,15 @@ DATA(insert OID = 1915 ( numeric_uplus PGNSP PGUID 12 f f t f i 1 1700 "1700
DESCR("unary plus");
DATA(insert OID = 1922 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "19 25 25" has_table_privilege_name_name - _null_ ));
DESCR("user privilege on relation by username, relname");
DESCR("user privilege on relation by username, rel name");
DATA(insert OID = 1923 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" has_table_privilege_name_id - _null_ ));
DESCR("user privilege on relation by username, rel oid");
DATA(insert OID = 1924 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" has_table_privilege_id_name - _null_ ));
DESCR("user privilege on relation by usesysid, relname");
DESCR("user privilege on relation by usesysid, rel name");
DATA(insert OID = 1925 ( has_table_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" has_table_privilege_id_id - _null_ ));
DESCR("user privilege on relation by usesysid, rel oid");
DATA(insert OID = 1926 ( has_table_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" has_table_privilege_name - _null_ ));
DESCR("current user privilege on relation by relname");
DESCR("current user privilege on relation by rel name");
DATA(insert OID = 1927 ( has_table_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" has_table_privilege_id - _null_ ));
DESCR("current user privilege on relation by rel oid");
......@@ -2881,11 +2881,23 @@ DESCR("int8 to bitstring");
DATA(insert OID = 2076 ( int8 PGNSP PGUID 12 f f t f i 1 20 "1560" bittoint8 - _null_ ));
DESCR("bitstring to int8");
DATA(insert OID = 2090 ( current_setting PGNSP PGUID 12 f f t f s 1 25 "25" show_config_by_name - _null_ ));
DATA(insert OID = 2077 ( current_setting PGNSP PGUID 12 f f t f s 1 25 "25" show_config_by_name - _null_ ));
DESCR("SHOW X as a function");
DATA(insert OID = 2091 ( set_config PGNSP PGUID 12 f f f f v 3 25 "25 25 16" set_config_by_name - _null_ ));
DATA(insert OID = 2078 ( set_config PGNSP PGUID 12 f f f f v 3 25 "25 25 16" set_config_by_name - _null_ ));
DESCR("SET X as a function");
DATA(insert OID = 2079 ( pg_table_is_visible PGNSP PGUID 12 f f t f s 1 16 "26" pg_table_is_visible - _null_ ));
DESCR("is table visible in search path?");
DATA(insert OID = 2080 ( pg_type_is_visible PGNSP PGUID 12 f f t f s 1 16 "26" pg_type_is_visible - _null_ ));
DESCR("is type visible in search path?");
DATA(insert OID = 2081 ( pg_function_is_visible PGNSP PGUID 12 f f t f s 1 16 "26" pg_function_is_visible - _null_ ));
DESCR("is function visible in search path?");
DATA(insert OID = 2082 ( pg_operator_is_visible PGNSP PGUID 12 f f t f s 1 16 "26" pg_operator_is_visible - _null_ ));
DESCR("is operator visible in search path?");
DATA(insert OID = 2083 ( pg_opclass_is_visible PGNSP PGUID 12 f f t f s 1 16 "26" pg_opclass_is_visible - _null_ ));
DESCR("is opclass visible in search path?");
/* Aggregates (moved here from pg_aggregate for 7.3) */
DATA(insert OID = 2100 ( avg PGNSP PGUID 12 t f f f i 1 1700 "20" aggregate_dummy - _null_ ));
......@@ -2983,7 +2995,58 @@ DATA(insert OID = 2247 ( fmgr_c_validator PGNSP PGUID 12 f f t f s 1 26 "23" f
DESCR("(internal)");
DATA(insert OID = 2248 ( fmgr_sql_validator PGNSP PGUID 12 f f t f s 1 26 "23" fmgr_sql_validator - _null_ ));
DESCR("(internal)");
#define SQLvalidatorId 2248
DATA(insert OID = 2250 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "19 25 25" has_database_privilege_name_name - _null_ ));
DESCR("user privilege on database by username, database name");
DATA(insert OID = 2251 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" has_database_privilege_name_id - _null_ ));
DESCR("user privilege on database by username, database oid");
DATA(insert OID = 2252 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" has_database_privilege_id_name - _null_ ));
DESCR("user privilege on database by usesysid, database name");
DATA(insert OID = 2253 ( has_database_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" has_database_privilege_id_id - _null_ ));
DESCR("user privilege on database by usesysid, database oid");
DATA(insert OID = 2254 ( has_database_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" has_database_privilege_name - _null_ ));
DESCR("current user privilege on database by database name");
DATA(insert OID = 2255 ( has_database_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" has_database_privilege_id - _null_ ));
DESCR("current user privilege on database by database oid");
DATA(insert OID = 2256 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "19 25 25" has_function_privilege_name_name - _null_ ));
DESCR("user privilege on function by username, function name");
DATA(insert OID = 2257 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" has_function_privilege_name_id - _null_ ));
DESCR("user privilege on function by username, function oid");
DATA(insert OID = 2258 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" has_function_privilege_id_name - _null_ ));
DESCR("user privilege on function by usesysid, function name");
DATA(insert OID = 2259 ( has_function_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" has_function_privilege_id_id - _null_ ));
DESCR("user privilege on function by usesysid, function oid");
DATA(insert OID = 2260 ( has_function_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" has_function_privilege_name - _null_ ));
DESCR("current user privilege on function by function name");
DATA(insert OID = 2261 ( has_function_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" has_function_privilege_id - _null_ ));
DESCR("current user privilege on function by function oid");
DATA(insert OID = 2262 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "19 25 25" has_language_privilege_name_name - _null_ ));
DESCR("user privilege on language by username, language name");
DATA(insert OID = 2263 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" has_language_privilege_name_id - _null_ ));
DESCR("user privilege on language by username, language oid");
DATA(insert OID = 2264 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" has_language_privilege_id_name - _null_ ));
DESCR("user privilege on language by usesysid, language name");
DATA(insert OID = 2265 ( has_language_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" has_language_privilege_id_id - _null_ ));
DESCR("user privilege on language by usesysid, language oid");
DATA(insert OID = 2266 ( has_language_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" has_language_privilege_name - _null_ ));
DESCR("current user privilege on language by language name");
DATA(insert OID = 2267 ( has_language_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" has_language_privilege_id - _null_ ));
DESCR("current user privilege on language by language oid");
DATA(insert OID = 2268 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "19 25 25" has_schema_privilege_name_name - _null_ ));
DESCR("user privilege on schema by username, schema name");
DATA(insert OID = 2269 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "19 26 25" has_schema_privilege_name_id - _null_ ));
DESCR("user privilege on schema by username, schema oid");
DATA(insert OID = 2270 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "23 25 25" has_schema_privilege_id_name - _null_ ));
DESCR("user privilege on schema by usesysid, schema name");
DATA(insert OID = 2271 ( has_schema_privilege PGNSP PGUID 12 f f t f s 3 16 "23 26 25" has_schema_privilege_id_id - _null_ ));
DESCR("user privilege on schema by usesysid, schema oid");
DATA(insert OID = 2272 ( has_schema_privilege PGNSP PGUID 12 f f t f s 2 16 "25 25" has_schema_privilege_name - _null_ ));
DESCR("current user privilege on schema by schema name");
DATA(insert OID = 2273 ( has_schema_privilege PGNSP PGUID 12 f f t f s 2 16 "26 25" has_schema_privilege_id - _null_ ));
DESCR("current user privilege on schema by schema oid");
/*
* Symbolic values for provolatile column: these indicate whether the result
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: dbcommands.h,v 1.24 2002/06/20 20:29:49 momjian Exp $
* $Id: dbcommands.h,v 1.25 2002/08/09 16:45:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -20,4 +20,7 @@ extern void createdb(const CreatedbStmt *stmt);
extern void dropdb(const char *dbname);
extern void AlterDatabaseSet(AlterDatabaseSetStmt *stmt);
extern Oid get_database_oid(const char *dbname);
extern Oid get_database_owner(Oid dbid);
#endif /* DBCOMMANDS_H */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: builtins.h,v 1.189 2002/08/06 14:11:05 tgl Exp $
* $Id: builtins.h,v 1.190 2002/08/09 16:45:16 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -29,6 +29,30 @@ extern Datum has_table_privilege_id_name(PG_FUNCTION_ARGS);
extern Datum has_table_privilege_id_id(PG_FUNCTION_ARGS);
extern Datum has_table_privilege_name(PG_FUNCTION_ARGS);
extern Datum has_table_privilege_id(PG_FUNCTION_ARGS);
extern Datum has_database_privilege_name_name(PG_FUNCTION_ARGS);
extern Datum has_database_privilege_name_id(PG_FUNCTION_ARGS);
extern Datum has_database_privilege_id_name(PG_FUNCTION_ARGS);
extern Datum has_database_privilege_id_id(PG_FUNCTION_ARGS);
extern Datum has_database_privilege_name(PG_FUNCTION_ARGS);
extern Datum has_database_privilege_id(PG_FUNCTION_ARGS);
extern Datum has_function_privilege_name_name(PG_FUNCTION_ARGS);
extern Datum has_function_privilege_name_id(PG_FUNCTION_ARGS);
extern Datum has_function_privilege_id_name(PG_FUNCTION_ARGS);
extern Datum has_function_privilege_id_id(PG_FUNCTION_ARGS);
extern Datum has_function_privilege_name(PG_FUNCTION_ARGS);
extern Datum has_function_privilege_id(PG_FUNCTION_ARGS);
extern Datum has_language_privilege_name_name(PG_FUNCTION_ARGS);
extern Datum has_language_privilege_name_id(PG_FUNCTION_ARGS);
extern Datum has_language_privilege_id_name(PG_FUNCTION_ARGS);
extern Datum has_language_privilege_id_id(PG_FUNCTION_ARGS);
extern Datum has_language_privilege_name(PG_FUNCTION_ARGS);
extern Datum has_language_privilege_id(PG_FUNCTION_ARGS);
extern Datum has_schema_privilege_name_name(PG_FUNCTION_ARGS);
extern Datum has_schema_privilege_name_id(PG_FUNCTION_ARGS);
extern Datum has_schema_privilege_id_name(PG_FUNCTION_ARGS);
extern Datum has_schema_privilege_id_id(PG_FUNCTION_ARGS);
extern Datum has_schema_privilege_name(PG_FUNCTION_ARGS);
extern Datum has_schema_privilege_id(PG_FUNCTION_ARGS);
/* bool.c */
extern Datum boolin(PG_FUNCTION_ARGS);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment