Restructure aclcheck error reporting to make permission-failure
messages more uniform and internationalizable: the global array aclcheck_error_strings[] is gone in favor of a subroutine aclcheck_error(). Partial implementation of namespace-related permission checks --- not all done yet.
This commit is contained in:
parent
aafe72efb2
commit
31c775adeb
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.66 2002/04/21 00:26:42 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.67 2002/04/27 03:45:00 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
|
@ -46,16 +46,7 @@ static void ExecuteGrantStmt_Namespace(GrantStmt *stmt);
|
||||||
|
|
||||||
static const char *privilege_to_string(AclMode privilege);
|
static const char *privilege_to_string(AclMode privilege);
|
||||||
|
|
||||||
static int32 aclcheck(Acl *acl, AclId id, uint32 idtype, AclMode mode);
|
static AclResult aclcheck(Acl *acl, AclId id, uint32 idtype, AclMode mode);
|
||||||
|
|
||||||
/* warning messages, now more explicit. */
|
|
||||||
/* MUST correspond to the order of the ACLCHECK_* result codes in acl.h. */
|
|
||||||
const char * const aclcheck_error_strings[] = {
|
|
||||||
"No error.",
|
|
||||||
"Permission denied.",
|
|
||||||
"Table does not exist.",
|
|
||||||
"Must be table owner."
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ACLDEBUG
|
#ifdef ACLDEBUG
|
||||||
|
@ -208,8 +199,7 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
|
||||||
pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
|
pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
|
||||||
|
|
||||||
if (!pg_class_ownercheck(relOid, GetUserId()))
|
if (!pg_class_ownercheck(relOid, GetUserId()))
|
||||||
elog(ERROR, "%s: permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, relvar->relname);
|
||||||
relvar->relname);
|
|
||||||
|
|
||||||
if (pg_class_tuple->relkind == RELKIND_INDEX)
|
if (pg_class_tuple->relkind == RELKIND_INDEX)
|
||||||
elog(ERROR, "\"%s\" is an index",
|
elog(ERROR, "\"%s\" is an index",
|
||||||
|
@ -409,7 +399,8 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
|
||||||
pg_proc_tuple = (Form_pg_proc) GETSTRUCT(tuple);
|
pg_proc_tuple = (Form_pg_proc) GETSTRUCT(tuple);
|
||||||
|
|
||||||
if (!pg_proc_ownercheck(oid, GetUserId()))
|
if (!pg_proc_ownercheck(oid, GetUserId()))
|
||||||
elog(ERROR, "permission denied");
|
aclcheck_error(ACLCHECK_NOT_OWNER,
|
||||||
|
NameStr(pg_proc_tuple->proname));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's no ACL, create a default using the pg_proc.proowner
|
* If there's no ACL, create a default using the pg_proc.proowner
|
||||||
|
@ -601,7 +592,7 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
|
||||||
pg_namespace_tuple = (Form_pg_namespace) GETSTRUCT(tuple);
|
pg_namespace_tuple = (Form_pg_namespace) GETSTRUCT(tuple);
|
||||||
|
|
||||||
if (!pg_namespace_ownercheck(tuple->t_data->t_oid, GetUserId()))
|
if (!pg_namespace_ownercheck(tuple->t_data->t_oid, GetUserId()))
|
||||||
elog(ERROR, "permission denied");
|
aclcheck_error(ACLCHECK_NOT_OWNER, nspname);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there's no ACL, create a default using the pg_namespace.nspowner
|
* If there's no ACL, create a default using the pg_namespace.nspowner
|
||||||
|
@ -776,6 +767,7 @@ in_group(AclId uid, AclId gid)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* aclcheck
|
* aclcheck
|
||||||
*
|
*
|
||||||
|
@ -785,7 +777,7 @@ in_group(AclId uid, AclId gid)
|
||||||
*
|
*
|
||||||
* The ACL list is expected to be sorted in standard order.
|
* The ACL list is expected to be sorted in standard order.
|
||||||
*/
|
*/
|
||||||
static int32
|
static AclResult
|
||||||
aclcheck(Acl *acl, AclId id, uint32 idtype, AclMode mode)
|
aclcheck(Acl *acl, AclId id, uint32 idtype, AclMode mode)
|
||||||
{
|
{
|
||||||
AclItem *aip,
|
AclItem *aip,
|
||||||
|
@ -903,14 +895,37 @@ aclcheck(Acl *acl, AclId id, uint32 idtype, AclMode mode)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exported routine for checking a user's access privileges to a table
|
* Standardized reporting of aclcheck permissions failures.
|
||||||
*
|
|
||||||
* Returns an ACLCHECK_* result code.
|
|
||||||
*/
|
*/
|
||||||
int32
|
void
|
||||||
|
aclcheck_error(AclResult errcode, const char *objectname)
|
||||||
|
{
|
||||||
|
switch (errcode)
|
||||||
|
{
|
||||||
|
case ACLCHECK_OK:
|
||||||
|
/* no error, so return to caller */
|
||||||
|
break;
|
||||||
|
case ACLCHECK_NO_PRIV:
|
||||||
|
elog(ERROR, "%s: permission denied", objectname);
|
||||||
|
break;
|
||||||
|
case ACLCHECK_NOT_OWNER:
|
||||||
|
elog(ERROR, "%s: must be owner", objectname);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elog(ERROR, "%s: unexpected AclResult %d",
|
||||||
|
objectname, (int) errcode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exported routine for checking a user's access privileges to a table
|
||||||
|
*/
|
||||||
|
AclResult
|
||||||
pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode)
|
pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode)
|
||||||
{
|
{
|
||||||
int32 result;
|
AclResult result;
|
||||||
bool usesuper,
|
bool usesuper,
|
||||||
usecatupd;
|
usecatupd;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
|
@ -1004,13 +1019,11 @@ pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exported routine for checking a user's access privileges to a database
|
* Exported routine for checking a user's access privileges to a database
|
||||||
*
|
|
||||||
* Returns an ACLCHECK_* result code.
|
|
||||||
*/
|
*/
|
||||||
int32
|
AclResult
|
||||||
pg_database_aclcheck(Oid db_oid, Oid userid, AclMode mode)
|
pg_database_aclcheck(Oid db_oid, Oid userid, AclMode mode)
|
||||||
{
|
{
|
||||||
int32 result;
|
AclResult result;
|
||||||
Relation pg_database;
|
Relation pg_database;
|
||||||
ScanKeyData entry[1];
|
ScanKeyData entry[1];
|
||||||
HeapScanDesc scan;
|
HeapScanDesc scan;
|
||||||
|
@ -1069,13 +1082,11 @@ pg_database_aclcheck(Oid db_oid, Oid userid, AclMode mode)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exported routine for checking a user's access privileges to a function
|
* Exported routine for checking a user's access privileges to a function
|
||||||
*
|
|
||||||
* Returns an ACLCHECK_* result code.
|
|
||||||
*/
|
*/
|
||||||
int32
|
AclResult
|
||||||
pg_proc_aclcheck(Oid proc_oid, Oid userid, AclMode mode)
|
pg_proc_aclcheck(Oid proc_oid, Oid userid, AclMode mode)
|
||||||
{
|
{
|
||||||
int32 result;
|
AclResult result;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Datum aclDatum;
|
Datum aclDatum;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
|
@ -1124,13 +1135,11 @@ pg_proc_aclcheck(Oid proc_oid, Oid userid, AclMode mode)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exported routine for checking a user's access privileges to a language
|
* Exported routine for checking a user's access privileges to a language
|
||||||
*
|
|
||||||
* Returns an ACLCHECK_* result code.
|
|
||||||
*/
|
*/
|
||||||
int32
|
AclResult
|
||||||
pg_language_aclcheck(Oid lang_oid, Oid userid, AclMode mode)
|
pg_language_aclcheck(Oid lang_oid, Oid userid, AclMode mode)
|
||||||
{
|
{
|
||||||
int32 result;
|
AclResult result;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Datum aclDatum;
|
Datum aclDatum;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
|
@ -1176,13 +1185,11 @@ pg_language_aclcheck(Oid lang_oid, Oid userid, AclMode mode)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exported routine for checking a user's access privileges to a namespace
|
* Exported routine for checking a user's access privileges to a namespace
|
||||||
*
|
|
||||||
* Returns an ACLCHECK_* result code.
|
|
||||||
*/
|
*/
|
||||||
int32
|
AclResult
|
||||||
pg_namespace_aclcheck(Oid nsp_oid, Oid userid, AclMode mode)
|
pg_namespace_aclcheck(Oid nsp_oid, Oid userid, AclMode mode)
|
||||||
{
|
{
|
||||||
int32 result;
|
AclResult result;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Datum aclDatum;
|
Datum aclDatum;
|
||||||
bool isNull;
|
bool isNull;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.13 2002/04/26 01:24:08 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.14 2002/04/27 03:45:00 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "storage/backendid.h"
|
#include "storage/backendid.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
|
@ -974,6 +975,16 @@ GetTempTableNamespace(void)
|
||||||
char namespaceName[NAMEDATALEN];
|
char namespaceName[NAMEDATALEN];
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First, do permission check to see if we are authorized to make
|
||||||
|
* temp tables. We use a nonstandard error message here since
|
||||||
|
* "databasename: permission denied" might be a tad cryptic.
|
||||||
|
*/
|
||||||
|
if (pg_database_aclcheck(MyDatabaseId, GetUserId(),
|
||||||
|
ACL_CREATE_TEMP) != ACLCHECK_OK)
|
||||||
|
elog(ERROR, "%s: not authorized to create temp tables",
|
||||||
|
DatabaseName);
|
||||||
|
|
||||||
snprintf(namespaceName, NAMEDATALEN, "pg_temp_%d", MyBackendId);
|
snprintf(namespaceName, NAMEDATALEN, "pg_temp_%d", MyBackendId);
|
||||||
|
|
||||||
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
namespaceId = GetSysCacheOid(NAMESPACENAME,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.67 2002/04/25 02:56:55 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.68 2002/04/27 03:45:00 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* these routines moved here from commands/define.c and somewhat cleaned up.
|
* these routines moved here from commands/define.c and somewhat cleaned up.
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
#include "parser/parse_oper.h"
|
#include "parser/parse_oper.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
@ -697,6 +698,7 @@ get_other_operator(List *otherOp, Oid otherLeftTypeId, Oid otherRightTypeId,
|
||||||
bool otherDefined;
|
bool otherDefined;
|
||||||
char *otherName;
|
char *otherName;
|
||||||
Oid otherNamespace;
|
Oid otherNamespace;
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
other_oid = OperatorLookup(otherOp,
|
other_oid = OperatorLookup(otherOp,
|
||||||
otherLeftTypeId,
|
otherLeftTypeId,
|
||||||
|
@ -727,6 +729,12 @@ get_other_operator(List *otherOp, Oid otherLeftTypeId, Oid otherRightTypeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* not in catalogs, different from operator, so make shell */
|
/* not in catalogs, different from operator, so make shell */
|
||||||
|
|
||||||
|
aclresult = pg_namespace_aclcheck(otherNamespace, GetUserId(),
|
||||||
|
ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(otherNamespace));
|
||||||
|
|
||||||
other_oid = OperatorShellMake(otherName,
|
other_oid = OperatorShellMake(otherName,
|
||||||
otherNamespace,
|
otherNamespace,
|
||||||
otherLeftTypeId,
|
otherLeftTypeId,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v 1.1 2002/04/15 05:22:03 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/aggregatecmds.c,v 1.2 2002/04/27 03:45:00 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/namespace.h"
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_aggregate.h"
|
#include "catalog/pg_aggregate.h"
|
||||||
|
#include "catalog/pg_proc.h"
|
||||||
#include "commands/comment.h"
|
#include "commands/comment.h"
|
||||||
#include "commands/defrem.h"
|
#include "commands/defrem.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
@ -45,6 +46,7 @@ DefineAggregate(List *names, List *parameters)
|
||||||
{
|
{
|
||||||
char *aggName;
|
char *aggName;
|
||||||
Oid aggNamespace;
|
Oid aggNamespace;
|
||||||
|
AclResult aclresult;
|
||||||
List *transfuncName = NIL;
|
List *transfuncName = NIL;
|
||||||
List *finalfuncName = NIL;
|
List *finalfuncName = NIL;
|
||||||
TypeName *baseType = NULL;
|
TypeName *baseType = NULL;
|
||||||
|
@ -57,6 +59,11 @@ DefineAggregate(List *names, List *parameters)
|
||||||
/* Convert list of names to a name and namespace */
|
/* Convert list of names to a name and namespace */
|
||||||
aggNamespace = QualifiedNameGetCreationNamespace(names, &aggName);
|
aggNamespace = QualifiedNameGetCreationNamespace(names, &aggName);
|
||||||
|
|
||||||
|
/* Check we have creation rights in target namespace */
|
||||||
|
aclresult = pg_namespace_aclcheck(aggNamespace, GetUserId(), ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(aggNamespace));
|
||||||
|
|
||||||
foreach(pl, parameters)
|
foreach(pl, parameters)
|
||||||
{
|
{
|
||||||
DefElem *defel = (DefElem *) lfirst(pl);
|
DefElem *defel = (DefElem *) lfirst(pl);
|
||||||
|
@ -157,20 +164,6 @@ RemoveAggregate(List *aggName, TypeName *aggType)
|
||||||
|
|
||||||
procOid = find_aggregate_func("RemoveAggregate", aggName, basetypeID);
|
procOid = find_aggregate_func("RemoveAggregate", aggName, basetypeID);
|
||||||
|
|
||||||
/* Permission check */
|
|
||||||
|
|
||||||
if (!pg_proc_ownercheck(procOid, GetUserId()))
|
|
||||||
{
|
|
||||||
if (basetypeID == InvalidOid)
|
|
||||||
elog(ERROR, "RemoveAggregate: aggregate %s for all types: permission denied",
|
|
||||||
NameListToString(aggName));
|
|
||||||
else
|
|
||||||
elog(ERROR, "RemoveAggregate: aggregate %s for type %s: permission denied",
|
|
||||||
NameListToString(aggName), format_type_be(basetypeID));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the pg_proc tuple */
|
|
||||||
|
|
||||||
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
tup = SearchSysCache(PROCOID,
|
tup = SearchSysCache(PROCOID,
|
||||||
|
@ -180,9 +173,16 @@ RemoveAggregate(List *aggName, TypeName *aggType)
|
||||||
elog(ERROR, "RemoveAggregate: couldn't find pg_proc tuple for %s",
|
elog(ERROR, "RemoveAggregate: couldn't find pg_proc tuple for %s",
|
||||||
NameListToString(aggName));
|
NameListToString(aggName));
|
||||||
|
|
||||||
|
/* Permission check: must own agg or its namespace */
|
||||||
|
if (!pg_proc_ownercheck(procOid, GetUserId()) &&
|
||||||
|
!pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
|
||||||
|
GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(aggName));
|
||||||
|
|
||||||
/* Delete any comments associated with this function */
|
/* Delete any comments associated with this function */
|
||||||
DeleteComments(procOid, RelationGetRelid(relation));
|
DeleteComments(procOid, RelationGetRelid(relation));
|
||||||
|
|
||||||
|
/* Remove the pg_proc tuple */
|
||||||
simple_heap_delete(relation, &tup->t_self);
|
simple_heap_delete(relation, &tup->t_self);
|
||||||
|
|
||||||
ReleaseSysCache(tup);
|
ReleaseSysCache(tup);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Copyright (c) 1999-2001, PostgreSQL Global Development Group
|
* Copyright (c) 1999-2001, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.44 2002/04/24 02:50:30 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.45 2002/04/27 03:45:00 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -324,8 +324,7 @@ CommentRelation(int objtype, List *relname, char *comment)
|
||||||
|
|
||||||
/* Check object security */
|
/* Check object security */
|
||||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
||||||
elog(ERROR, "you are not permitted to comment on class '%s'",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(relation));
|
||||||
RelationGetRelationName(relation));
|
|
||||||
|
|
||||||
/* Next, verify that the relation type matches the intent */
|
/* Next, verify that the relation type matches the intent */
|
||||||
|
|
||||||
|
@ -395,8 +394,7 @@ CommentAttribute(List *qualname, char *comment)
|
||||||
/* Check object security */
|
/* Check object security */
|
||||||
|
|
||||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
||||||
elog(ERROR, "you are not permitted to comment on class '%s'",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(relation));
|
||||||
RelationGetRelationName(relation));
|
|
||||||
|
|
||||||
/* Now, fetch the attribute number from the system cache */
|
/* Now, fetch the attribute number from the system cache */
|
||||||
|
|
||||||
|
@ -498,7 +496,7 @@ CommentRule(List *qualname, char *comment)
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
Oid ruleoid;
|
Oid ruleoid;
|
||||||
Oid classoid;
|
Oid classoid;
|
||||||
int32 aclcheck;
|
AclResult aclcheck;
|
||||||
|
|
||||||
/* Separate relname and trig name */
|
/* Separate relname and trig name */
|
||||||
nnames = length(qualname);
|
nnames = length(qualname);
|
||||||
|
@ -573,8 +571,7 @@ CommentRule(List *qualname, char *comment)
|
||||||
|
|
||||||
aclcheck = pg_class_aclcheck(reloid, GetUserId(), ACL_RULE);
|
aclcheck = pg_class_aclcheck(reloid, GetUserId(), ACL_RULE);
|
||||||
if (aclcheck != ACLCHECK_OK)
|
if (aclcheck != ACLCHECK_OK)
|
||||||
elog(ERROR, "you are not permitted to comment on rule '%s'",
|
aclcheck_error(aclcheck, rulename);
|
||||||
rulename);
|
|
||||||
|
|
||||||
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
|
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */
|
||||||
|
|
||||||
|
@ -613,8 +610,7 @@ CommentType(List *typename, char *comment)
|
||||||
/* Check object security */
|
/* Check object security */
|
||||||
|
|
||||||
if (!pg_type_ownercheck(oid, GetUserId()))
|
if (!pg_type_ownercheck(oid, GetUserId()))
|
||||||
elog(ERROR, "you are not permitted to comment on type %s",
|
aclcheck_error(ACLCHECK_NOT_OWNER, TypeNameToString(tname));
|
||||||
TypeNameToString(tname));
|
|
||||||
|
|
||||||
/* Call CreateComments() to create/drop the comments */
|
/* Call CreateComments() to create/drop the comments */
|
||||||
|
|
||||||
|
@ -649,14 +645,7 @@ CommentAggregate(List *aggregate, List *arguments, char *comment)
|
||||||
/* Next, validate the user's attempt to comment */
|
/* Next, validate the user's attempt to comment */
|
||||||
|
|
||||||
if (!pg_proc_ownercheck(oid, GetUserId()))
|
if (!pg_proc_ownercheck(oid, GetUserId()))
|
||||||
{
|
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(aggregate));
|
||||||
if (baseoid == InvalidOid)
|
|
||||||
elog(ERROR, "you are not permitted to comment on aggregate %s for all types",
|
|
||||||
NameListToString(aggregate));
|
|
||||||
else
|
|
||||||
elog(ERROR, "you are not permitted to comment on aggregate %s for type %s",
|
|
||||||
NameListToString(aggregate), format_type_be(baseoid));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call CreateComments() to create/drop the comments */
|
/* Call CreateComments() to create/drop the comments */
|
||||||
|
|
||||||
|
@ -685,8 +674,7 @@ CommentProc(List *function, List *arguments, char *comment)
|
||||||
/* Now, validate the user's ability to comment on this function */
|
/* Now, validate the user's ability to comment on this function */
|
||||||
|
|
||||||
if (!pg_proc_ownercheck(oid, GetUserId()))
|
if (!pg_proc_ownercheck(oid, GetUserId()))
|
||||||
elog(ERROR, "you are not permitted to comment on function %s",
|
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(function));
|
||||||
NameListToString(function));
|
|
||||||
|
|
||||||
/* Call CreateComments() to create/drop the comments */
|
/* Call CreateComments() to create/drop the comments */
|
||||||
|
|
||||||
|
@ -723,8 +711,7 @@ CommentOperator(List *opername, List *arguments, char *comment)
|
||||||
/* Valid user's ability to comment on this operator */
|
/* Valid user's ability to comment on this operator */
|
||||||
|
|
||||||
if (!pg_oper_ownercheck(oid, GetUserId()))
|
if (!pg_oper_ownercheck(oid, GetUserId()))
|
||||||
elog(ERROR, "you are not permitted to comment on operator '%s'",
|
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(opername));
|
||||||
NameListToString(opername));
|
|
||||||
|
|
||||||
/* Get the procedure associated with the operator */
|
/* Get the procedure associated with the operator */
|
||||||
|
|
||||||
|
@ -775,8 +762,7 @@ CommentTrigger(List *qualname, char *comment)
|
||||||
/* Check object security */
|
/* Check object security */
|
||||||
|
|
||||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
||||||
elog(ERROR, "you are not permitted to comment on trigger '%s' for relation '%s'",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(relation));
|
||||||
trigname, RelationGetRelationName(relation));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch the trigger tuple from pg_trigger. There can be only one
|
* Fetch the trigger tuple from pg_trigger. There can be only one
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.152 2002/03/29 19:06:05 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.153 2002/04/27 03:45:00 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -266,8 +266,8 @@ DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe,
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
Relation rel;
|
Relation rel;
|
||||||
const AclMode required_access = (from ? ACL_INSERT : ACL_SELECT);
|
AclMode required_access = (from ? ACL_INSERT : ACL_SELECT);
|
||||||
int32 aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open and lock the relation, using the appropriate lock type.
|
* Open and lock the relation, using the appropriate lock type.
|
||||||
|
@ -278,9 +278,7 @@ DoCopy(const RangeVar *relation, bool binary, bool oids, bool from, bool pipe,
|
||||||
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
|
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
|
||||||
required_access);
|
required_access);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
elog(ERROR, "%s: %s",
|
aclcheck_error(aclresult, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel),
|
|
||||||
aclcheck_error_strings[aclresult]);
|
|
||||||
if (!pipe && !superuser())
|
if (!pipe && !superuser())
|
||||||
elog(ERROR, "You must have Postgres superuser privilege to do a COPY "
|
elog(ERROR, "You must have Postgres superuser privilege to do a COPY "
|
||||||
"directly to or from a file. Anyone can COPY to stdout or "
|
"directly to or from a file. Anyone can COPY to stdout or "
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.2 2002/04/21 00:26:42 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.3 2002/04/27 03:45:01 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* These routines take the parse tree and pick out the
|
* These routines take the parse tree and pick out the
|
||||||
|
@ -86,6 +86,7 @@ compute_return_type(TypeName *returnType, Oid languageOid,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
|
AclResult aclresult;
|
||||||
char *typname;
|
char *typname;
|
||||||
|
|
||||||
if (languageOid == SQLlanguageId)
|
if (languageOid == SQLlanguageId)
|
||||||
|
@ -94,6 +95,10 @@ compute_return_type(TypeName *returnType, Oid languageOid,
|
||||||
typnam);
|
typnam);
|
||||||
namespaceId = QualifiedNameGetCreationNamespace(returnType->names,
|
namespaceId = QualifiedNameGetCreationNamespace(returnType->names,
|
||||||
&typname);
|
&typname);
|
||||||
|
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
|
||||||
|
ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(namespaceId));
|
||||||
rettype = TypeShellMake(typname, namespaceId);
|
rettype = TypeShellMake(typname, namespaceId);
|
||||||
if (!OidIsValid(rettype))
|
if (!OidIsValid(rettype))
|
||||||
elog(ERROR, "could not create type %s", typnam);
|
elog(ERROR, "could not create type %s", typnam);
|
||||||
|
@ -295,6 +300,7 @@ CreateFunction(ProcedureStmt *stmt)
|
||||||
Oid languageOid;
|
Oid languageOid;
|
||||||
char *funcname;
|
char *funcname;
|
||||||
Oid namespaceId;
|
Oid namespaceId;
|
||||||
|
AclResult aclresult;
|
||||||
int parameterCount;
|
int parameterCount;
|
||||||
Oid parameterTypes[FUNC_MAX_ARGS];
|
Oid parameterTypes[FUNC_MAX_ARGS];
|
||||||
int32 byte_pct,
|
int32 byte_pct,
|
||||||
|
@ -311,6 +317,11 @@ CreateFunction(ProcedureStmt *stmt)
|
||||||
namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
|
namespaceId = QualifiedNameGetCreationNamespace(stmt->funcname,
|
||||||
&funcname);
|
&funcname);
|
||||||
|
|
||||||
|
/* Check we have creation rights in target namespace */
|
||||||
|
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(), ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(namespaceId));
|
||||||
|
|
||||||
/* Convert language name to canonical case */
|
/* Convert language name to canonical case */
|
||||||
case_translate_language_name(stmt->language, languageName);
|
case_translate_language_name(stmt->language, languageName);
|
||||||
|
|
||||||
|
@ -324,10 +335,21 @@ CreateFunction(ProcedureStmt *stmt)
|
||||||
languageOid = languageTuple->t_data->t_oid;
|
languageOid = languageTuple->t_data->t_oid;
|
||||||
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
|
languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
|
||||||
|
|
||||||
if (!((languageStruct->lanpltrusted
|
if (languageStruct->lanpltrusted)
|
||||||
&& pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE) == ACLCHECK_OK)
|
{
|
||||||
|| superuser()))
|
/* if trusted language, need USAGE privilege */
|
||||||
elog(ERROR, "permission denied");
|
AclResult aclresult;
|
||||||
|
|
||||||
|
aclresult = pg_language_aclcheck(languageOid, GetUserId(), ACL_USAGE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, NameStr(languageStruct->lanname));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* if untrusted language, must be superuser */
|
||||||
|
if (!superuser())
|
||||||
|
aclcheck_error(ACLCHECK_NO_PRIV, NameStr(languageStruct->lanname));
|
||||||
|
}
|
||||||
|
|
||||||
ReleaseSysCache(languageTuple);
|
ReleaseSysCache(languageTuple);
|
||||||
|
|
||||||
|
@ -404,9 +426,11 @@ RemoveFunction(List *functionName, /* function name to be removed */
|
||||||
elog(ERROR, "RemoveFunction: couldn't find tuple for function %s",
|
elog(ERROR, "RemoveFunction: couldn't find tuple for function %s",
|
||||||
NameListToString(functionName));
|
NameListToString(functionName));
|
||||||
|
|
||||||
if (!pg_proc_ownercheck(funcOid, GetUserId()))
|
/* Permission check: must own func or its namespace */
|
||||||
elog(ERROR, "RemoveFunction: function '%s': permission denied",
|
if (!pg_proc_ownercheck(funcOid, GetUserId()) &&
|
||||||
NameListToString(functionName));
|
!pg_namespace_ownercheck(((Form_pg_proc) GETSTRUCT(tup))->pronamespace,
|
||||||
|
GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(functionName));
|
||||||
|
|
||||||
if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
|
if (((Form_pg_proc) GETSTRUCT(tup))->proisagg)
|
||||||
elog(ERROR, "RemoveFunction: function '%s' is an aggregate"
|
elog(ERROR, "RemoveFunction: function '%s' is an aggregate"
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.71 2002/04/17 20:57:56 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.72 2002/04/27 03:45:01 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
#include "parser/parsetree.h"
|
#include "parser/parsetree.h"
|
||||||
#include "parser/parse_coerce.h"
|
#include "parser/parse_coerce.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
@ -73,6 +74,7 @@ DefineIndex(RangeVar *heapRelation,
|
||||||
Oid *classObjectId;
|
Oid *classObjectId;
|
||||||
Oid accessMethodId;
|
Oid accessMethodId;
|
||||||
Oid relationId;
|
Oid relationId;
|
||||||
|
Oid namespaceId;
|
||||||
Relation rel;
|
Relation rel;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Form_pg_am accessMethodForm;
|
Form_pg_am accessMethodForm;
|
||||||
|
@ -102,6 +104,7 @@ DefineIndex(RangeVar *heapRelation,
|
||||||
heapRelation->relname);
|
heapRelation->relname);
|
||||||
|
|
||||||
relationId = RelationGetRelid(rel);
|
relationId = RelationGetRelid(rel);
|
||||||
|
namespaceId = RelationGetNamespace(rel);
|
||||||
|
|
||||||
if (!IsBootstrapProcessingMode() &&
|
if (!IsBootstrapProcessingMode() &&
|
||||||
IsSystemRelation(rel) &&
|
IsSystemRelation(rel) &&
|
||||||
|
@ -110,6 +113,22 @@ DefineIndex(RangeVar *heapRelation,
|
||||||
|
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify we (still) have CREATE rights in the rel's namespace.
|
||||||
|
* (Presumably we did when the rel was created, but maybe not anymore.)
|
||||||
|
* Skip check if bootstrapping, since permissions machinery may not
|
||||||
|
* be working yet; also, always allow if it's a temp table.
|
||||||
|
*/
|
||||||
|
if (!IsBootstrapProcessingMode() && !isTempNamespace(namespaceId))
|
||||||
|
{
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
|
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
|
||||||
|
ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(namespaceId));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* look up the access method, verify it can handle the requested
|
* look up the access method, verify it can handle the requested
|
||||||
* features
|
* features
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/lockcmds.c,v 1.1 2002/04/15 05:22:03 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/lockcmds.c,v 1.2 2002/04/27 03:45:01 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -19,6 +19,7 @@
|
||||||
#include "commands/lockcmds.h"
|
#include "commands/lockcmds.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -38,7 +39,7 @@ LockTableCommand(LockStmt *lockstmt)
|
||||||
{
|
{
|
||||||
RangeVar *relation = lfirst(p);
|
RangeVar *relation = lfirst(p);
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
int32 aclresult;
|
AclResult aclresult;
|
||||||
Relation rel;
|
Relation rel;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,7 +56,7 @@ LockTableCommand(LockStmt *lockstmt)
|
||||||
ACL_UPDATE | ACL_DELETE);
|
ACL_UPDATE | ACL_DELETE);
|
||||||
|
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
elog(ERROR, "LOCK TABLE: permission denied");
|
aclcheck_error(aclresult, get_rel_name(reloid));
|
||||||
|
|
||||||
rel = relation_open(reloid, lockstmt->mode);
|
rel = relation_open(reloid, lockstmt->mode);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/operatorcmds.c,v 1.2 2002/04/16 23:08:10 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/operatorcmds.c,v 1.3 2002/04/27 03:45:01 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
|
@ -44,6 +44,7 @@
|
||||||
#include "parser/parse_oper.h"
|
#include "parser/parse_oper.h"
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ DefineOperator(List *names, List *parameters)
|
||||||
{
|
{
|
||||||
char *oprName;
|
char *oprName;
|
||||||
Oid oprNamespace;
|
Oid oprNamespace;
|
||||||
|
AclResult aclresult;
|
||||||
uint16 precedence = 0; /* operator precedence */
|
uint16 precedence = 0; /* operator precedence */
|
||||||
bool canHash = false; /* operator hashes */
|
bool canHash = false; /* operator hashes */
|
||||||
bool canMerge = false; /* operator merges */
|
bool canMerge = false; /* operator merges */
|
||||||
|
@ -85,6 +87,11 @@ DefineOperator(List *names, List *parameters)
|
||||||
/* Convert list of names to a name and namespace */
|
/* Convert list of names to a name and namespace */
|
||||||
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
|
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
|
||||||
|
|
||||||
|
/* Check we have creation rights in target namespace */
|
||||||
|
aclresult = pg_namespace_aclcheck(oprNamespace, GetUserId(), ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(oprNamespace));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* loop over the definition list and extract the information we need.
|
* loop over the definition list and extract the information we need.
|
||||||
*/
|
*/
|
||||||
|
@ -226,14 +233,15 @@ RemoveOperator(List *operatorName, /* operator name */
|
||||||
tup = SearchSysCacheCopy(OPEROID,
|
tup = SearchSysCacheCopy(OPEROID,
|
||||||
ObjectIdGetDatum(operOid),
|
ObjectIdGetDatum(operOid),
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
|
|
||||||
if (!HeapTupleIsValid(tup)) /* should not happen */
|
if (!HeapTupleIsValid(tup)) /* should not happen */
|
||||||
elog(ERROR, "RemoveOperator: failed to find tuple for operator '%s'",
|
elog(ERROR, "RemoveOperator: failed to find tuple for operator '%s'",
|
||||||
NameListToString(operatorName));
|
NameListToString(operatorName));
|
||||||
|
|
||||||
if (!pg_oper_ownercheck(operOid, GetUserId()))
|
/* Permission check: must own operator or its namespace */
|
||||||
elog(ERROR, "RemoveOperator: operator '%s': permission denied",
|
if (!pg_oper_ownercheck(operOid, GetUserId()) &&
|
||||||
NameListToString(operatorName));
|
!pg_namespace_ownercheck(((Form_pg_operator) GETSTRUCT(tup))->oprnamespace,
|
||||||
|
GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, NameListToString(operatorName));
|
||||||
|
|
||||||
/* Delete any comments associated with this operator */
|
/* Delete any comments associated with this operator */
|
||||||
DeleteComments(operOid, RelationGetRelid(relation));
|
DeleteComments(operOid, RelationGetRelid(relation));
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.1 2002/04/15 05:22:03 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/schemacmds.c,v 1.2 2002/04/27 03:45:01 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -20,6 +20,7 @@
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "parser/analyze.h"
|
#include "parser/analyze.h"
|
||||||
#include "tcop/utility.h"
|
#include "tcop/utility.h"
|
||||||
|
#include "utils/acl.h"
|
||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,9 +37,14 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
||||||
const char *owner_name;
|
const char *owner_name;
|
||||||
Oid owner_userid;
|
Oid owner_userid;
|
||||||
Oid saved_userid;
|
Oid saved_userid;
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
saved_userid = GetUserId();
|
saved_userid = GetUserId();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Figure out user identities.
|
||||||
|
*/
|
||||||
|
|
||||||
if (!authId)
|
if (!authId)
|
||||||
{
|
{
|
||||||
owner_userid = saved_userid;
|
owner_userid = saved_userid;
|
||||||
|
@ -67,6 +73,13 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
|
||||||
owner_name, authId);
|
owner_name, authId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Permissions checks.
|
||||||
|
*/
|
||||||
|
aclresult = pg_database_aclcheck(MyDatabaseId, saved_userid, ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, DatabaseName);
|
||||||
|
|
||||||
if (!allowSystemTableMods && IsReservedName(schemaName))
|
if (!allowSystemTableMods && IsReservedName(schemaName))
|
||||||
elog(ERROR, "CREATE SCHEMA: Illegal schema name: \"%s\" -- pg_ is reserved for system schemas",
|
elog(ERROR, "CREATE SCHEMA: Illegal schema name: \"%s\" -- pg_ is reserved for system schemas",
|
||||||
schemaName);
|
schemaName);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.10 2002/04/26 19:29:47 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.11 2002/04/27 03:45:01 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -106,10 +106,22 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look up the namespace in which we are supposed to create the
|
* Look up the namespace in which we are supposed to create the
|
||||||
* relation.
|
* relation. Check we have permission to create there.
|
||||||
|
* Skip check if bootstrapping, since permissions machinery may not
|
||||||
|
* be working yet; also, always allow if it's a temp table.
|
||||||
*/
|
*/
|
||||||
namespaceId = RangeVarGetCreationNamespace(stmt->relation);
|
namespaceId = RangeVarGetCreationNamespace(stmt->relation);
|
||||||
|
|
||||||
|
if (!IsBootstrapProcessingMode() && !isTempNamespace(namespaceId))
|
||||||
|
{
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
|
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
|
||||||
|
ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(namespaceId));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Merge domain attributes into the known columns before processing table
|
* Merge domain attributes into the known columns before processing table
|
||||||
* inheritance. Otherwise we risk adding double constraints to a
|
* inheritance. Otherwise we risk adding double constraints to a
|
||||||
|
@ -307,8 +319,7 @@ TruncateRelation(const RangeVar *relation)
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(relid, GetUserId()))
|
if (!pg_class_ownercheck(relid, GetUserId()))
|
||||||
elog(ERROR, "you do not own relation \"%s\"",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
/* Keep the lock until transaction commit */
|
/* Keep the lock until transaction commit */
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
|
@ -483,8 +494,8 @@ MergeAttributes(List *schema, List *supers, bool istemp,
|
||||||
* demand that creator of a child table own the parent.
|
* demand that creator of a child table own the parent.
|
||||||
*/
|
*/
|
||||||
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
|
||||||
elog(ERROR, "you do not own table \"%s\"",
|
aclcheck_error(ACLCHECK_NOT_OWNER,
|
||||||
parent->relname);
|
RelationGetRelationName(relation));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reject duplications in the list of parents.
|
* Reject duplications in the list of parents.
|
||||||
|
@ -1003,8 +1014,8 @@ renameatt(Oid relid,
|
||||||
elog(ERROR, "renameatt: class \"%s\" is a system catalog",
|
elog(ERROR, "renameatt: class \"%s\" is a system catalog",
|
||||||
RelationGetRelationName(targetrelation));
|
RelationGetRelationName(targetrelation));
|
||||||
if (!pg_class_ownercheck(relid, GetUserId()))
|
if (!pg_class_ownercheck(relid, GetUserId()))
|
||||||
elog(ERROR, "renameatt: you do not own class \"%s\"",
|
aclcheck_error(ACLCHECK_NOT_OWNER,
|
||||||
RelationGetRelationName(targetrelation));
|
RelationGetRelationName(targetrelation));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if the 'recurse' flag is set then we are supposed to rename this
|
* if the 'recurse' flag is set then we are supposed to rename this
|
||||||
|
@ -1558,8 +1569,7 @@ AlterTableAddColumn(Oid myrelid,
|
||||||
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recurse to add the column to child classes, if requested.
|
* Recurse to add the column to child classes, if requested.
|
||||||
|
@ -1761,8 +1771,7 @@ AlterTableAlterColumnDropNotNull(Oid myrelid,
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Propagate to children if desired
|
* Propagate to children if desired
|
||||||
|
@ -1912,8 +1921,7 @@ AlterTableAlterColumnSetNotNull(Oid myrelid,
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Propagate to children if desired
|
* Propagate to children if desired
|
||||||
|
@ -2048,8 +2056,7 @@ AlterTableAlterColumnDefault(Oid myrelid,
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Propagate to children if desired
|
* Propagate to children if desired
|
||||||
|
@ -2208,8 +2215,7 @@ AlterTableAlterColumnFlags(Oid myrelid,
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the supplied parameters before anything else
|
* Check the supplied parameters before anything else
|
||||||
|
@ -2370,8 +2376,7 @@ AlterTableAddConstraint(Oid myrelid,
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
if (inh)
|
if (inh)
|
||||||
{
|
{
|
||||||
|
@ -2695,8 +2700,7 @@ AlterTableDropConstraint(Oid myrelid,
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
if (!pg_class_ownercheck(myrelid, GetUserId()))
|
||||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since all we have is the name of the constraint, we have to look
|
* Since all we have is the name of the constraint, we have to look
|
||||||
|
@ -2857,8 +2861,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(relOid, GetUserId()))
|
if (!pg_class_ownercheck(relOid, GetUserId()))
|
||||||
elog(ERROR, "ALTER TABLE: \"%s\": permission denied",
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
RelationGetRelationName(rel));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lock the pg_class tuple for update (is that really needed?)
|
* lock the pg_class tuple for update (is that really needed?)
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.115 2002/04/26 19:29:47 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.116 2002/04/27 03:45:02 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -58,6 +58,7 @@ CreateTrigger(CreateTrigStmt *stmt)
|
||||||
Datum values[Natts_pg_trigger];
|
Datum values[Natts_pg_trigger];
|
||||||
char nulls[Natts_pg_trigger];
|
char nulls[Natts_pg_trigger];
|
||||||
Relation rel;
|
Relation rel;
|
||||||
|
AclResult aclresult;
|
||||||
Relation tgrel;
|
Relation tgrel;
|
||||||
SysScanDesc tgscan;
|
SysScanDesc tgscan;
|
||||||
ScanKeyData key;
|
ScanKeyData key;
|
||||||
|
@ -84,10 +85,10 @@ CreateTrigger(CreateTrigStmt *stmt)
|
||||||
elog(ERROR, "CreateTrigger: can't create trigger for system relation %s",
|
elog(ERROR, "CreateTrigger: can't create trigger for system relation %s",
|
||||||
stmt->relation->relname);
|
stmt->relation->relname);
|
||||||
|
|
||||||
if (pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
|
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
|
||||||
stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER)
|
stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER);
|
||||||
!= ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
elog(ERROR, "permission denied");
|
aclcheck_error(aclresult, RelationGetRelationName(rel));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If trigger is an RI constraint, use trigger name as constraint name
|
* If trigger is an RI constraint, use trigger name as constraint name
|
||||||
|
@ -337,8 +338,7 @@ DropTrigger(Oid relid, const char *trigname)
|
||||||
RelationGetRelationName(rel));
|
RelationGetRelationName(rel));
|
||||||
|
|
||||||
if (!pg_class_ownercheck(relid, GetUserId()))
|
if (!pg_class_ownercheck(relid, GetUserId()))
|
||||||
elog(ERROR, "%s: %s", RelationGetRelationName(rel),
|
aclcheck_error(ACLCHECK_NOT_OWNER, RelationGetRelationName(rel));
|
||||||
aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search pg_trigger, delete target trigger, count remaining triggers
|
* Search pg_trigger, delete target trigger, count remaining triggers
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.1 2002/04/15 05:22:03 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.2 2002/04/27 03:45:02 tgl Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
|
@ -45,6 +45,7 @@
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ DefineType(List *names, List *parameters)
|
||||||
{
|
{
|
||||||
char *typeName;
|
char *typeName;
|
||||||
Oid typeNamespace;
|
Oid typeNamespace;
|
||||||
|
AclResult aclresult;
|
||||||
int16 internalLength = -1; /* int2 */
|
int16 internalLength = -1; /* int2 */
|
||||||
int16 externalLength = -1; /* int2 */
|
int16 externalLength = -1; /* int2 */
|
||||||
Oid elemType = InvalidOid;
|
Oid elemType = InvalidOid;
|
||||||
|
@ -83,6 +85,11 @@ DefineType(List *names, List *parameters)
|
||||||
/* Convert list of names to a name and namespace */
|
/* Convert list of names to a name and namespace */
|
||||||
typeNamespace = QualifiedNameGetCreationNamespace(names, &typeName);
|
typeNamespace = QualifiedNameGetCreationNamespace(names, &typeName);
|
||||||
|
|
||||||
|
/* Check we have creation rights in target namespace */
|
||||||
|
aclresult = pg_namespace_aclcheck(typeNamespace, GetUserId(), ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(typeNamespace));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Type names must be one character shorter than other names, allowing
|
* Type names must be one character shorter than other names, allowing
|
||||||
* room to create the corresponding array type name with prepended
|
* room to create the corresponding array type name with prepended
|
||||||
|
@ -288,9 +295,11 @@ RemoveType(List *names)
|
||||||
elog(ERROR, "Type \"%s\" does not exist",
|
elog(ERROR, "Type \"%s\" does not exist",
|
||||||
TypeNameToString(typename));
|
TypeNameToString(typename));
|
||||||
|
|
||||||
if (!pg_type_ownercheck(typeoid, GetUserId()))
|
/* Permission check: must own type or its namespace */
|
||||||
elog(ERROR, "RemoveType: type '%s': permission denied",
|
if (!pg_type_ownercheck(typeoid, GetUserId()) &&
|
||||||
TypeNameToString(typename));
|
!pg_namespace_ownercheck(((Form_pg_type) GETSTRUCT(tup))->typnamespace,
|
||||||
|
GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, TypeNameToString(typename));
|
||||||
|
|
||||||
/* Delete any comments associated with this type */
|
/* Delete any comments associated with this type */
|
||||||
DeleteComments(typeoid, RelationGetRelid(relation));
|
DeleteComments(typeoid, RelationGetRelid(relation));
|
||||||
|
@ -334,6 +343,7 @@ DefineDomain(CreateDomainStmt *stmt)
|
||||||
{
|
{
|
||||||
char *domainName;
|
char *domainName;
|
||||||
Oid domainNamespace;
|
Oid domainNamespace;
|
||||||
|
AclResult aclresult;
|
||||||
int16 internalLength;
|
int16 internalLength;
|
||||||
int16 externalLength;
|
int16 externalLength;
|
||||||
Oid inputProcedure;
|
Oid inputProcedure;
|
||||||
|
@ -360,6 +370,12 @@ DefineDomain(CreateDomainStmt *stmt)
|
||||||
domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname,
|
domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname,
|
||||||
&domainName);
|
&domainName);
|
||||||
|
|
||||||
|
/* Check we have creation rights in target namespace */
|
||||||
|
aclresult = pg_namespace_aclcheck(domainNamespace, GetUserId(),
|
||||||
|
ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_namespace_name(domainNamespace));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Domainnames, unlike typenames don't need to account for the '_'
|
* Domainnames, unlike typenames don't need to account for the '_'
|
||||||
* prefix. So they can be one character longer.
|
* prefix. So they can be one character longer.
|
||||||
|
@ -586,9 +602,11 @@ RemoveDomain(List *names, int behavior)
|
||||||
elog(ERROR, "RemoveDomain: type '%s' does not exist",
|
elog(ERROR, "RemoveDomain: type '%s' does not exist",
|
||||||
TypeNameToString(typename));
|
TypeNameToString(typename));
|
||||||
|
|
||||||
if (!pg_type_ownercheck(typeoid, GetUserId()))
|
/* Permission check: must own type or its namespace */
|
||||||
elog(ERROR, "RemoveDomain: type '%s': permission denied",
|
if (!pg_type_ownercheck(typeoid, GetUserId()) &&
|
||||||
TypeNameToString(typename));
|
!pg_namespace_ownercheck(((Form_pg_type) GETSTRUCT(tup))->typnamespace,
|
||||||
|
GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, TypeNameToString(typename));
|
||||||
|
|
||||||
/* Check that this is actually a domain */
|
/* Check that this is actually a domain */
|
||||||
typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype;
|
typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype;
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.158 2002/04/15 05:22:04 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.159 2002/04/27 03:45:02 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -360,7 +360,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
|
||||||
{
|
{
|
||||||
Oid relOid;
|
Oid relOid;
|
||||||
Oid userid;
|
Oid userid;
|
||||||
int32 aclcheck_result;
|
AclResult aclcheck_result;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's a subquery RTE, ignore it --- it will be checked when
|
* If it's a subquery RTE, ignore it --- it will be checked when
|
||||||
|
@ -388,9 +388,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
|
||||||
{
|
{
|
||||||
aclcheck_result = CHECK(ACL_SELECT);
|
aclcheck_result = CHECK(ACL_SELECT);
|
||||||
if (aclcheck_result != ACLCHECK_OK)
|
if (aclcheck_result != ACLCHECK_OK)
|
||||||
elog(ERROR, "%s: %s",
|
aclcheck_error(aclcheck_result, get_rel_name(relOid));
|
||||||
get_rel_name(relOid),
|
|
||||||
aclcheck_error_strings[aclcheck_result]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rte->checkForWrite)
|
if (rte->checkForWrite)
|
||||||
|
@ -419,9 +417,7 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (aclcheck_result != ACLCHECK_OK)
|
if (aclcheck_result != ACLCHECK_OK)
|
||||||
elog(ERROR, "%s: %s",
|
aclcheck_error(aclcheck_result, get_rel_name(relOid));
|
||||||
get_rel_name(relOid),
|
|
||||||
aclcheck_error_strings[aclcheck_result]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,7 +697,7 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
||||||
if (!parseTree->isPortal)
|
if (!parseTree->isPortal)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* a select into table
|
* a select into table --- need to create the "into" table
|
||||||
*/
|
*/
|
||||||
if (parseTree->into != NULL)
|
if (parseTree->into != NULL)
|
||||||
{
|
{
|
||||||
|
@ -711,11 +707,22 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
|
||||||
TupleDesc tupdesc;
|
TupleDesc tupdesc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create the "into" relation
|
* find namespace to create in, check permissions
|
||||||
*/
|
*/
|
||||||
intoName = parseTree->into->relname;
|
intoName = parseTree->into->relname;
|
||||||
namespaceId = RangeVarGetCreationNamespace(parseTree->into);
|
namespaceId = RangeVarGetCreationNamespace(parseTree->into);
|
||||||
|
|
||||||
|
if (!isTempNamespace(namespaceId))
|
||||||
|
{
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
|
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
|
||||||
|
ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult,
|
||||||
|
get_namespace_name(namespaceId));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* have to copy tupType to get rid of constraints
|
* have to copy tupType to get rid of constraints
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.90 2002/02/18 23:11:13 petere Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.91 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -658,9 +658,6 @@ ExecMakeFunctionResult(FunctionCachePtr fcache,
|
||||||
bool hasSetArg;
|
bool hasSetArg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!fcache->permission_ok)
|
|
||||||
elog(ERROR, "permission denied");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* arguments is a list of expressions to evaluate before passing to
|
* arguments is a list of expressions to evaluate before passing to
|
||||||
* the function manager. We skip the evaluation if it was already
|
* the function manager. We skip the evaluation if it was already
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.68 2002/04/19 23:13:54 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.69 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -127,7 +127,7 @@ DefineQueryRewrite(RuleStmt *stmt)
|
||||||
*event_qualP;
|
*event_qualP;
|
||||||
List *l;
|
List *l;
|
||||||
Query *query;
|
Query *query;
|
||||||
int32 aclcheck_result;
|
AclResult aclresult;
|
||||||
bool RelisBecomingView = false;
|
bool RelisBecomingView = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -144,11 +144,9 @@ DefineQueryRewrite(RuleStmt *stmt)
|
||||||
/*
|
/*
|
||||||
* Check user has permission to apply rules to this relation.
|
* Check user has permission to apply rules to this relation.
|
||||||
*/
|
*/
|
||||||
aclcheck_result = pg_class_aclcheck(ev_relid, GetUserId(), ACL_RULE);
|
aclresult = pg_class_aclcheck(ev_relid, GetUserId(), ACL_RULE);
|
||||||
if (aclcheck_result != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
elog(ERROR, "%s: %s",
|
aclcheck_error(aclresult, RelationGetRelationName(event_relation));
|
||||||
RelationGetRelationName(event_relation),
|
|
||||||
aclcheck_error_strings[aclcheck_result]);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No rule actions that modify OLD or NEW
|
* No rule actions that modify OLD or NEW
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.48 2002/04/18 20:01:09 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.49 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -42,7 +42,7 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName)
|
||||||
Oid ruleId;
|
Oid ruleId;
|
||||||
Oid eventRelationOid;
|
Oid eventRelationOid;
|
||||||
bool hasMoreRules;
|
bool hasMoreRules;
|
||||||
int32 aclcheck_result;
|
AclResult aclresult;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the pg_rewrite relation.
|
* Open the pg_rewrite relation.
|
||||||
|
@ -82,12 +82,9 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName)
|
||||||
/*
|
/*
|
||||||
* Verify user has appropriate permissions.
|
* Verify user has appropriate permissions.
|
||||||
*/
|
*/
|
||||||
aclcheck_result = pg_class_aclcheck(eventRelationOid, GetUserId(),
|
aclresult = pg_class_aclcheck(eventRelationOid, GetUserId(), ACL_RULE);
|
||||||
ACL_RULE);
|
if (aclresult != ACLCHECK_OK)
|
||||||
if (aclcheck_result != ACLCHECK_OK)
|
aclcheck_error(aclresult, RelationGetRelationName(event_relation));
|
||||||
elog(ERROR, "%s: %s",
|
|
||||||
RelationGetRelationName(event_relation),
|
|
||||||
aclcheck_error_strings[aclcheck_result]);
|
|
||||||
|
|
||||||
/* do not allow the removal of a view's SELECT rule */
|
/* do not allow the removal of a view's SELECT rule */
|
||||||
if (event_relation->rd_rel->relkind == RELKIND_VIEW &&
|
if (event_relation->rd_rel->relkind == RELKIND_VIEW &&
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.151 2002/04/24 02:48:55 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.152 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -124,9 +124,10 @@ CheckDropPermissions(RangeVar *rel, char rightkind)
|
||||||
if (classform->relkind != rightkind)
|
if (classform->relkind != rightkind)
|
||||||
DropErrorMsg(rel->relname, classform->relkind, rightkind);
|
DropErrorMsg(rel->relname, classform->relkind, rightkind);
|
||||||
|
|
||||||
if (!pg_class_ownercheck(relOid, GetUserId()))
|
/* Allow DROP to either table owner or schema owner */
|
||||||
elog(ERROR, "you do not own %s \"%s\"",
|
if (!pg_class_ownercheck(relOid, GetUserId()) &&
|
||||||
rentry->name, rel->relname);
|
!pg_namespace_ownercheck(classform->relnamespace, GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, rel->relname);
|
||||||
|
|
||||||
if (!allowSystemTableMods && IsSystemClass(classform))
|
if (!allowSystemTableMods && IsSystemClass(classform))
|
||||||
elog(ERROR, "%s \"%s\" is a system %s",
|
elog(ERROR, "%s \"%s\" is a system %s",
|
||||||
|
@ -149,8 +150,7 @@ CheckOwnership(RangeVar *rel, bool noCatalogs)
|
||||||
elog(ERROR, "Relation \"%s\" does not exist", rel->relname);
|
elog(ERROR, "Relation \"%s\" does not exist", rel->relname);
|
||||||
|
|
||||||
if (!pg_class_ownercheck(relOid, GetUserId()))
|
if (!pg_class_ownercheck(relOid, GetUserId()))
|
||||||
elog(ERROR, "%s: %s", rel->relname,
|
aclcheck_error(ACLCHECK_NOT_OWNER, rel->relname);
|
||||||
aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
|
|
||||||
|
|
||||||
if (noCatalogs)
|
if (noCatalogs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.72 2002/04/26 01:24:08 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.73 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -664,7 +664,7 @@ has_table_privilege_name_name(PG_FUNCTION_ARGS)
|
||||||
int32 usesysid;
|
int32 usesysid;
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
AclMode mode;
|
AclMode mode;
|
||||||
int32 aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup userid based on username
|
* Lookup userid based on username
|
||||||
|
@ -709,7 +709,7 @@ has_table_privilege_name(PG_FUNCTION_ARGS)
|
||||||
int32 usesysid;
|
int32 usesysid;
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
AclMode mode;
|
AclMode mode;
|
||||||
int32 aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
usesysid = GetUserId();
|
usesysid = GetUserId();
|
||||||
|
|
||||||
|
@ -750,7 +750,7 @@ has_table_privilege_name_id(PG_FUNCTION_ARGS)
|
||||||
text *priv_type_text = PG_GETARG_TEXT_P(2);
|
text *priv_type_text = PG_GETARG_TEXT_P(2);
|
||||||
int32 usesysid;
|
int32 usesysid;
|
||||||
AclMode mode;
|
AclMode mode;
|
||||||
int32 aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup userid based on username
|
* Lookup userid based on username
|
||||||
|
@ -789,7 +789,7 @@ has_table_privilege_id(PG_FUNCTION_ARGS)
|
||||||
text *priv_type_text = PG_GETARG_TEXT_P(1);
|
text *priv_type_text = PG_GETARG_TEXT_P(1);
|
||||||
int32 usesysid;
|
int32 usesysid;
|
||||||
AclMode mode;
|
AclMode mode;
|
||||||
int32 aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
usesysid = GetUserId();
|
usesysid = GetUserId();
|
||||||
|
|
||||||
|
@ -825,7 +825,7 @@ has_table_privilege_id_name(PG_FUNCTION_ARGS)
|
||||||
text *priv_type_text = PG_GETARG_TEXT_P(2);
|
text *priv_type_text = PG_GETARG_TEXT_P(2);
|
||||||
Oid reloid;
|
Oid reloid;
|
||||||
AclMode mode;
|
AclMode mode;
|
||||||
int32 aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lookup rel OID based on relname
|
* Lookup rel OID based on relname
|
||||||
|
@ -863,7 +863,7 @@ has_table_privilege_id_id(PG_FUNCTION_ARGS)
|
||||||
Oid reloid = PG_GETARG_OID(1);
|
Oid reloid = PG_GETARG_OID(1);
|
||||||
text *priv_type_text = PG_GETARG_TEXT_P(2);
|
text *priv_type_text = PG_GETARG_TEXT_P(2);
|
||||||
AclMode mode;
|
AclMode mode;
|
||||||
int32 aclresult;
|
AclResult aclresult;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert priv_type_text to an AclMode
|
* Convert priv_type_text to an AclMode
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.43 2002/04/21 00:26:43 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/Attic/fcache.c,v 1.44 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/acl.h"
|
#include "utils/acl.h"
|
||||||
#include "utils/fcache.h"
|
#include "utils/fcache.h"
|
||||||
|
#include "utils/lsyscache.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,6 +27,12 @@ FunctionCachePtr
|
||||||
init_fcache(Oid foid, int nargs, MemoryContext fcacheCxt)
|
init_fcache(Oid foid, int nargs, MemoryContext fcacheCxt)
|
||||||
{
|
{
|
||||||
FunctionCachePtr retval;
|
FunctionCachePtr retval;
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
|
/* Check permission to call function */
|
||||||
|
aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, get_func_name(foid));
|
||||||
|
|
||||||
/* Safety check (should never fail, as parser should check sooner) */
|
/* Safety check (should never fail, as parser should check sooner) */
|
||||||
if (nargs > FUNC_MAX_ARGS)
|
if (nargs > FUNC_MAX_ARGS)
|
||||||
|
@ -42,7 +49,5 @@ init_fcache(Oid foid, int nargs, MemoryContext fcacheCxt)
|
||||||
/* Initialize additional info */
|
/* Initialize additional info */
|
||||||
retval->setArgsValid = false;
|
retval->setArgsValid = false;
|
||||||
|
|
||||||
retval->permission_ok = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE) == ACLCHECK_OK;
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.70 2002/04/16 23:08:11 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.71 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Eventually, the index information should go through here, too.
|
* Eventually, the index information should go through here, too.
|
||||||
|
@ -564,6 +564,33 @@ get_oprjoin(Oid opno)
|
||||||
|
|
||||||
/* ---------- FUNCTION CACHE ---------- */
|
/* ---------- FUNCTION CACHE ---------- */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_func_name
|
||||||
|
* returns the name of the function with the given funcid
|
||||||
|
*
|
||||||
|
* Note: returns a palloc'd copy of the string, or NULL if no such function.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
get_func_name(Oid funcid)
|
||||||
|
{
|
||||||
|
HeapTuple tp;
|
||||||
|
|
||||||
|
tp = SearchSysCache(PROCOID,
|
||||||
|
ObjectIdGetDatum(funcid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (HeapTupleIsValid(tp))
|
||||||
|
{
|
||||||
|
Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp);
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
result = pstrdup(NameStr(functup->proname));
|
||||||
|
ReleaseSysCache(tp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_func_rettype
|
* get_func_rettype
|
||||||
* Given procedure id, return the function's result type.
|
* Given procedure id, return the function's result type.
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: acl.h,v 1.43 2002/04/21 00:26:44 tgl Exp $
|
* $Id: acl.h,v 1.44 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* For backward-compatibility purposes we have to allow there
|
* For backward-compatibility purposes we have to allow there
|
||||||
|
@ -165,13 +165,12 @@ typedef ArrayType IdList;
|
||||||
|
|
||||||
|
|
||||||
/* result codes for pg_*_aclcheck */
|
/* result codes for pg_*_aclcheck */
|
||||||
#define ACLCHECK_OK 0
|
typedef enum
|
||||||
#define ACLCHECK_NO_PRIV 1
|
{
|
||||||
#define ACLCHECK_NO_CLASS 2
|
ACLCHECK_OK = 0,
|
||||||
#define ACLCHECK_NOT_OWNER 3
|
ACLCHECK_NO_PRIV,
|
||||||
|
ACLCHECK_NOT_OWNER
|
||||||
/* error messages (index by ACLCHECK_* result code). set in aclchk.c. */
|
} AclResult;
|
||||||
extern const char * const aclcheck_error_strings[];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* routines used internally
|
* routines used internally
|
||||||
|
@ -181,7 +180,7 @@ extern Acl *aclinsert3(const Acl *old_acl, const AclItem *mod_aip,
|
||||||
unsigned modechg);
|
unsigned modechg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* exported routines (from acl.c)
|
* SQL functions (from acl.c)
|
||||||
*/
|
*/
|
||||||
extern Datum aclitemin(PG_FUNCTION_ARGS);
|
extern Datum aclitemin(PG_FUNCTION_ARGS);
|
||||||
extern Datum aclitemout(PG_FUNCTION_ARGS);
|
extern Datum aclitemout(PG_FUNCTION_ARGS);
|
||||||
|
@ -196,12 +195,13 @@ extern void ExecuteGrantStmt(GrantStmt *stmt);
|
||||||
extern AclId get_grosysid(char *groname);
|
extern AclId get_grosysid(char *groname);
|
||||||
extern char *get_groname(AclId grosysid);
|
extern char *get_groname(AclId grosysid);
|
||||||
|
|
||||||
/* these return ACLCHECK_* result codes */
|
extern AclResult pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode);
|
||||||
extern int32 pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode);
|
extern AclResult pg_database_aclcheck(Oid db_oid, Oid userid, AclMode mode);
|
||||||
extern int32 pg_database_aclcheck(Oid db_oid, Oid userid, AclMode mode);
|
extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid userid, AclMode mode);
|
||||||
extern int32 pg_proc_aclcheck(Oid proc_oid, Oid userid, AclMode mode);
|
extern AclResult pg_language_aclcheck(Oid lang_oid, Oid userid, AclMode mode);
|
||||||
extern int32 pg_language_aclcheck(Oid lang_oid, Oid userid, AclMode mode);
|
extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid userid, AclMode mode);
|
||||||
extern int32 pg_namespace_aclcheck(Oid nsp_oid, Oid userid, AclMode mode);
|
|
||||||
|
extern void aclcheck_error(AclResult errcode, const char *objectname);
|
||||||
|
|
||||||
/* ownercheck routines just return true (owner) or false (not) */
|
/* ownercheck routines just return true (owner) or false (not) */
|
||||||
extern bool pg_class_ownercheck(Oid class_oid, Oid userid);
|
extern bool pg_class_ownercheck(Oid class_oid, Oid userid);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: fcache.h,v 1.21 2002/02/18 23:11:46 petere Exp $
|
* $Id: fcache.h,v 1.22 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -41,8 +41,6 @@ typedef struct FunctionCache
|
||||||
*/
|
*/
|
||||||
FmgrInfo func;
|
FmgrInfo func;
|
||||||
|
|
||||||
bool permission_ok;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setArgsValid is true when we are evaluating a set-valued function
|
* setArgsValid is true when we are evaluating a set-valued function
|
||||||
* and we are in the middle of a call series; we want to pass the same
|
* and we are in the middle of a call series; we want to pass the same
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: lsyscache.h,v 1.49 2002/04/05 00:31:35 tgl Exp $
|
* $Id: lsyscache.h,v 1.50 2002/04/27 03:45:03 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -37,6 +37,7 @@ extern Oid get_commutator(Oid opno);
|
||||||
extern Oid get_negator(Oid opno);
|
extern Oid get_negator(Oid opno);
|
||||||
extern RegProcedure get_oprrest(Oid opno);
|
extern RegProcedure get_oprrest(Oid opno);
|
||||||
extern RegProcedure get_oprjoin(Oid opno);
|
extern RegProcedure get_oprjoin(Oid opno);
|
||||||
|
extern char *get_func_name(Oid funcid);
|
||||||
extern Oid get_func_rettype(Oid funcid);
|
extern Oid get_func_rettype(Oid funcid);
|
||||||
extern char func_volatile(Oid funcid);
|
extern char func_volatile(Oid funcid);
|
||||||
extern Oid get_relname_relid(const char *relname, Oid relnamespace);
|
extern Oid get_relname_relid(const char *relname, Oid relnamespace);
|
||||||
|
|
|
@ -69,11 +69,11 @@ SELECT * FROM atest2; -- ok
|
||||||
|
|
||||||
INSERT INTO atest1 VALUES (2, 'two'); -- ok
|
INSERT INTO atest1 VALUES (2, 'two'); -- ok
|
||||||
INSERT INTO atest2 VALUES ('foo', true); -- fail
|
INSERT INTO atest2 VALUES ('foo', true); -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok
|
INSERT INTO atest1 SELECT 1, b FROM atest1; -- ok
|
||||||
UPDATE atest1 SET a = 1 WHERE a = 2; -- ok
|
UPDATE atest1 SET a = 1 WHERE a = 2; -- ok
|
||||||
UPDATE atest2 SET col2 = NOT col2; -- fail
|
UPDATE atest2 SET col2 = NOT col2; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
SELECT * FROM atest1 FOR UPDATE; -- ok
|
SELECT * FROM atest1 FOR UPDATE; -- ok
|
||||||
a | b
|
a | b
|
||||||
---+-----
|
---+-----
|
||||||
|
@ -82,15 +82,15 @@ SELECT * FROM atest1 FOR UPDATE; -- ok
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
SELECT * FROM atest2 FOR UPDATE; -- fail
|
SELECT * FROM atest2 FOR UPDATE; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
DELETE FROM atest2; -- fail
|
DELETE FROM atest2; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- fail
|
||||||
ERROR: LOCK TABLE: permission denied
|
ERROR: atest2: permission denied
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
GRANT ALL ON atest1 TO PUBLIC; -- fail
|
||||||
ERROR: atest1: permission denied
|
ERROR: atest1: must be owner
|
||||||
-- checks in subquery, both ok
|
-- checks in subquery, both ok
|
||||||
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
|
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
|
||||||
a | b
|
a | b
|
||||||
|
@ -117,33 +117,33 @@ SELECT * FROM atest1; -- ok
|
||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
SELECT * FROM atest2; -- fail
|
SELECT * FROM atest2; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
INSERT INTO atest1 VALUES (2, 'two'); -- fail
|
INSERT INTO atest1 VALUES (2, 'two'); -- fail
|
||||||
ERROR: atest1: Permission denied.
|
ERROR: atest1: permission denied
|
||||||
INSERT INTO atest2 VALUES ('foo', true); -- fail
|
INSERT INTO atest2 VALUES ('foo', true); -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
INSERT INTO atest1 SELECT 1, b FROM atest1; -- fail
|
INSERT INTO atest1 SELECT 1, b FROM atest1; -- fail
|
||||||
ERROR: atest1: Permission denied.
|
ERROR: atest1: permission denied
|
||||||
UPDATE atest1 SET a = 1 WHERE a = 2; -- fail
|
UPDATE atest1 SET a = 1 WHERE a = 2; -- fail
|
||||||
ERROR: atest1: Permission denied.
|
ERROR: atest1: permission denied
|
||||||
UPDATE atest2 SET col2 = NULL; -- ok
|
UPDATE atest2 SET col2 = NULL; -- ok
|
||||||
UPDATE atest2 SET col2 = NOT col2; -- fails; requires SELECT on atest2
|
UPDATE atest2 SET col2 = NOT col2; -- fails; requires SELECT on atest2
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
UPDATE atest2 SET col2 = true WHERE atest1.a = 5; -- ok
|
UPDATE atest2 SET col2 = true WHERE atest1.a = 5; -- ok
|
||||||
SELECT * FROM atest1 FOR UPDATE; -- fail
|
SELECT * FROM atest1 FOR UPDATE; -- fail
|
||||||
ERROR: atest1: Permission denied.
|
ERROR: atest1: permission denied
|
||||||
SELECT * FROM atest2 FOR UPDATE; -- fail
|
SELECT * FROM atest2 FOR UPDATE; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
DELETE FROM atest2; -- fail
|
DELETE FROM atest2; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
LOCK atest2 IN ACCESS EXCLUSIVE MODE; -- ok
|
||||||
COPY atest2 FROM stdin; -- fail
|
COPY atest2 FROM stdin; -- fail
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
-- checks in subquery, both fail
|
-- checks in subquery, both fail
|
||||||
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
|
SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
|
SELECT * FROM atest2 WHERE ( col1 IN ( SELECT b FROM atest1 ) );
|
||||||
ERROR: atest2: Permission denied.
|
ERROR: atest2: permission denied
|
||||||
SET SESSION AUTHORIZATION regressuser4;
|
SET SESSION AUTHORIZATION regressuser4;
|
||||||
COPY atest2 FROM stdin; -- ok
|
COPY atest2 FROM stdin; -- ok
|
||||||
SELECT * FROM atest1; -- ok
|
SELECT * FROM atest1; -- ok
|
||||||
|
@ -159,7 +159,7 @@ CREATE TABLE atest3 (one int, two int, three int);
|
||||||
GRANT DELETE ON atest3 TO GROUP regressgroup2;
|
GRANT DELETE ON atest3 TO GROUP regressgroup2;
|
||||||
SET SESSION AUTHORIZATION regressuser1;
|
SET SESSION AUTHORIZATION regressuser1;
|
||||||
SELECT * FROM atest3; -- fail
|
SELECT * FROM atest3; -- fail
|
||||||
ERROR: atest3: Permission denied.
|
ERROR: atest3: permission denied
|
||||||
DELETE FROM atest3; -- ok
|
DELETE FROM atest3; -- ok
|
||||||
-- views
|
-- views
|
||||||
SET SESSION AUTHORIZATION regressuser3;
|
SET SESSION AUTHORIZATION regressuser3;
|
||||||
|
@ -214,10 +214,10 @@ SELECT testfunc1(5), testfunc2(5); -- ok
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
|
CREATE FUNCTION testfunc3(int) RETURNS int AS 'select 2 * $1;' LANGUAGE sql; -- fail
|
||||||
ERROR: permission denied
|
ERROR: sql: permission denied
|
||||||
SET SESSION AUTHORIZATION regressuser3;
|
SET SESSION AUTHORIZATION regressuser3;
|
||||||
SELECT testfunc1(5); -- fail
|
SELECT testfunc1(5); -- fail
|
||||||
ERROR: permission denied
|
ERROR: testfunc1: permission denied
|
||||||
SET SESSION AUTHORIZATION regressuser4;
|
SET SESSION AUTHORIZATION regressuser4;
|
||||||
SELECT testfunc1(5); -- ok
|
SELECT testfunc1(5); -- ok
|
||||||
testfunc1
|
testfunc1
|
||||||
|
@ -226,7 +226,7 @@ SELECT testfunc1(5); -- ok
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
DROP FUNCTION testfunc1(int); -- fail
|
DROP FUNCTION testfunc1(int); -- fail
|
||||||
ERROR: RemoveFunction: function 'testfunc1': permission denied
|
ERROR: testfunc1: must be owner
|
||||||
\c -
|
\c -
|
||||||
DROP FUNCTION testfunc1(int); -- ok
|
DROP FUNCTION testfunc1(int); -- ok
|
||||||
-- restore to sanity
|
-- restore to sanity
|
||||||
|
|
Loading…
Reference in New Issue