aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/commands/analyze.c12
-rw-r--r--src/backend/commands/comment.c35
-rw-r--r--src/backend/commands/define.c8
-rw-r--r--src/backend/commands/indexcmds.c30
-rw-r--r--src/backend/commands/proclang.c16
-rw-r--r--src/backend/commands/vacuum.c13
-rw-r--r--src/backend/libpq/be-fsstubs.c4
-rw-r--r--src/backend/utils/misc/superuser.c56
-rw-r--r--src/include/catalog/pg_shadow.h6
-rw-r--r--src/include/miscadmin.h8
10 files changed, 94 insertions, 94 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 28ec8d648ef..c650ff88a1a 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.19 2001/06/06 21:29:17 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.20 2001/06/13 21:44:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -193,16 +193,18 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
ReleaseSysCache(tuple);
/*
- * Open the class, getting only a read lock on it, and check permissions
+ * Open the class, getting only a read lock on it, and check permissions.
+ * Permissions check should match vacuum's check!
*/
onerel = heap_open(relid, AccessShareLock);
- if (!pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
- RELNAME))
+ if (! (pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
+ RELNAME) ||
+ (is_dbadmin(MyDatabaseId) && !onerel->rd_rel->relisshared)))
{
/* No need for a notice if we already complained during VACUUM */
if (!vacstmt->vacuum)
- elog(NOTICE, "Skipping \"%s\" --- only table owner can ANALYZE it",
+ elog(NOTICE, "Skipping \"%s\" --- only table or database owner can ANALYZE it",
RelationGetRelationName(onerel));
heap_close(onerel, NoLock);
CommitTransactionCommand();
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 695c7401e71..39668f867e0 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -4,10 +4,10 @@
*
* PostgreSQL object comments utility code.
*
- * Copyright (c) 1999, PostgreSQL Global Development Group
+ * Copyright (c) 1999-2001, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.29 2001/06/05 19:34:56 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.30 2001/06/13 21:44:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -21,7 +21,6 @@
#include "catalog/pg_database.h"
#include "catalog/pg_description.h"
#include "catalog/pg_operator.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_type.h"
#include "catalog/pg_class.h"
@@ -389,16 +388,11 @@ CommentAttribute(char *relname, char *attrname, char *comment)
static void
CommentDatabase(char *database, char *comment)
{
-
Relation pg_database;
- HeapTuple dbtuple,
- usertuple;
ScanKeyData entry;
HeapScanDesc scan;
+ HeapTuple dbtuple;
Oid oid;
- bool superuser;
- int32 dba;
- Oid userid;
/*** First find the tuple in pg_database for the database ***/
@@ -408,33 +402,17 @@ CommentDatabase(char *database, char *comment)
scan = heap_beginscan(pg_database, 0, SnapshotNow, 1, &entry);
dbtuple = heap_getnext(scan, 0);
- /*** Validate database exists, and fetch the dba id and oid ***/
+ /*** Validate database exists, and fetch the db oid ***/
if (!HeapTupleIsValid(dbtuple))
elog(ERROR, "database '%s' does not exist", database);
- dba = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba;
oid = dbtuple->t_data->t_oid;
- /*** Now, fetch user information ***/
-
- userid = GetUserId();
- usertuple = SearchSysCache(SHADOWSYSID,
- ObjectIdGetDatum(userid),
- 0, 0, 0);
- if (!HeapTupleIsValid(usertuple))
- elog(ERROR, "invalid user id %u", (unsigned) userid);
- superuser = ((Form_pg_shadow) GETSTRUCT(usertuple))->usesuper;
- ReleaseSysCache(usertuple);
+ /*** Allow if the user matches the database dba or is a superuser ***/
- /*** Allow if the userid matches the database dba or is a superuser ***/
-
-#ifndef NO_SECURITY
- if (!(superuser || (userid == dba)))
- {
+ if (!(superuser() || is_dbadmin(oid)))
elog(ERROR, "you are not permitted to comment on database '%s'",
database);
- }
-#endif
/*** Create the comments with the pg_database oid ***/
@@ -444,7 +422,6 @@ CommentDatabase(char *database, char *comment)
heap_endscan(scan);
heap_close(pg_database, AccessShareLock);
-
}
/*------------------------------------------------------------------
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index 98a6e351476..b5852b6fffa 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.55 2001/05/18 21:24:18 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.56 2001/06/13 21:44:40 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -33,21 +33,21 @@
*
*-------------------------------------------------------------------------
*/
+#include "postgres.h"
+
#include <ctype.h>
#include <math.h>
-#include "postgres.h"
-
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_aggregate.h"
#include "catalog/pg_language.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
-#include "catalog/pg_shadow.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "fmgr.h"
+#include "miscadmin.h"
#include "optimizer/cost.h"
#include "parser/parse_expr.h"
#include "tcop/dest.h"
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 373a68fbf30..108c4ea3780 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.49 2001/05/31 18:16:55 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.50 2001/06/13 21:44:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,7 +28,6 @@
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
-#include "catalog/pg_shadow.h"
#include "commands/defrem.h"
#include "miscadmin.h"
#include "optimizer/clauses.h"
@@ -712,14 +711,9 @@ ReindexTable(const char *name, bool force)
void
ReindexDatabase(const char *dbname, bool force, bool all)
{
- Relation relation,
- relationRelation;
- HeapTuple dbtuple,
- tuple;
+ Relation relationRelation;
HeapScanDesc scan;
- int4 db_owner;
- Oid db_id;
- ScanKeyData scankey;
+ HeapTuple tuple;
MemoryContext private_context;
MemoryContext old;
int relcnt,
@@ -730,24 +724,12 @@ ReindexDatabase(const char *dbname, bool force, bool all)
AssertArg(dbname);
- relation = heap_openr(DatabaseRelationName, AccessShareLock);
- ScanKeyEntryInitialize(&scankey, 0, Anum_pg_database_datname,
- F_NAMEEQ, NameGetDatum(dbname));
- scan = heap_beginscan(relation, 0, SnapshotNow, 1, &scankey);
- dbtuple = heap_getnext(scan, 0);
- if (!HeapTupleIsValid(dbtuple))
- elog(ERROR, "Database \"%s\" does not exist", dbname);
- db_id = dbtuple->t_data->t_oid;
- db_owner = ((Form_pg_database) GETSTRUCT(dbtuple))->datdba;
- heap_endscan(scan);
- heap_close(relation, NoLock);
+ if (strcmp(dbname, DatabaseName) != 0)
+ elog(ERROR, "REINDEX DATABASE: Can be executed only on the currently open database.");
- if (GetUserId() != db_owner && !superuser())
+ if (! (superuser() || is_dbadmin(MyDatabaseId)))
elog(ERROR, "REINDEX DATABASE: Permission denied.");
- if (db_id != MyDatabaseId)
- elog(ERROR, "REINDEX DATABASE: Can be executed only on the currently open database.");
-
/*
* We cannot run inside a user transaction block; if we were inside a
* transaction, then our commit- and start-transaction-command calls
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 43327c7a65a..120c5d8b008 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -3,20 +3,26 @@
* proclang.c
* PostgreSQL PROCEDURAL LANGUAGE support code.
*
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.28 2001/06/13 21:44:40 tgl Exp $
+ *
*-------------------------------------------------------------------------
*/
-#include <ctype.h>
-
#include "postgres.h"
+#include <ctype.h>
+
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
-#include "catalog/pg_shadow.h"
#include "commands/proclang.h"
#include "fmgr.h"
+#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/syscache.h"
@@ -63,10 +69,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
* Check permission
*/
if (!superuser())
- {
elog(ERROR, "Only users with Postgres superuser privilege are "
"permitted to create procedural languages");
- }
/*
* Translate the language name and check that this language doesn't
@@ -150,10 +154,8 @@ DropProceduralLanguage(DropPLangStmt *stmt)
* Check permission
*/
if (!superuser())
- {
elog(ERROR, "Only users with Postgres superuser privilege are "
"permitted to drop procedural languages");
- }
/*
* Translate the language name, check that this language exist and is
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 3cba0395201..33d5409364a 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.195 2001/05/25 15:45:32 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.196 2001/06/13 21:44:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -437,15 +437,20 @@ vacuum_rel(Oid relid)
/*
* Open the class, get an exclusive lock on it, and check permissions.
*
+ * We allow the user to vacuum a table if he is superuser, the table
+ * owner, or the database owner (but in the latter case, only if it's
+ * not a shared relation). pg_ownercheck includes the superuser case.
+ *
* Note we choose to treat permissions failure as a NOTICE and keep
* trying to vacuum the rest of the DB --- is this appropriate?
*/
onerel = heap_open(relid, AccessExclusiveLock);
- if (!pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
- RELNAME))
+ if (! (pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
+ RELNAME) ||
+ (is_dbadmin(MyDatabaseId) && !onerel->rd_rel->relisshared)))
{
- elog(NOTICE, "Skipping \"%s\" --- only table owner can VACUUM it",
+ elog(NOTICE, "Skipping \"%s\" --- only table or database owner can VACUUM it",
RelationGetRelationName(onerel));
heap_close(onerel, AccessExclusiveLock);
CommitTransactionCommand();
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index 4d50ee1ae12..b0a759bc008 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.58 2001/03/22 03:59:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.59 2001/06/13 21:44:41 tgl Exp $
*
* NOTES
* This should be moved to a more appropriate place. It is here
@@ -39,9 +39,9 @@
#include <sys/stat.h>
#include <unistd.h>
-#include "catalog/pg_shadow.h"
#include "libpq/be-fsstubs.h"
#include "libpq/libpq-fs.h"
+#include "miscadmin.h"
#include "storage/large_object.h"
#include "utils/memutils.h"
diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c
index e539d57347b..73cfe8cb979 100644
--- a/src/backend/utils/misc/superuser.c
+++ b/src/backend/utils/misc/superuser.c
@@ -1,35 +1,38 @@
/*-------------------------------------------------------------------------
*
* superuser.c
- *
* The superuser() function. Determines if user has superuser privilege.
+ * Also, a function to check for the owner (datdba) of a database.
+ *
*
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.17 2001/01/24 19:43:16 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/superuser.c,v 1.18 2001/06/13 21:44:41 tgl Exp $
*
- * DESCRIPTION
- * See superuser().
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
+
+#include "access/heapam.h"
+#include "catalog/catname.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_shadow.h"
#include "utils/syscache.h"
#include "miscadmin.h"
+#include "utils/fmgroids.h"
+
+/*
+ * The Postgres user running this command has Postgres superuser privileges
+ */
bool
superuser(void)
{
-/*--------------------------------------------------------------------------
- The Postgres user running this command has Postgres superuser
- privileges.
---------------------------------------------------------------------------*/
+ bool result = false;
HeapTuple utup;
- bool result;
utup = SearchSysCache(SHADOWSYSID,
ObjectIdGetDatum(GetUserId()),
@@ -38,7 +41,36 @@ superuser(void)
{
result = ((Form_pg_shadow) GETSTRUCT(utup))->usesuper;
ReleaseSysCache(utup);
- return result;
}
- return false;
+ return result;
+}
+
+/*
+ * The Postgres user running this command is the owner of the specified
+ * database.
+ */
+bool
+is_dbadmin(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, 0, SnapshotNow, 1, entry);
+ dbtuple = heap_getnext(scan, 0);
+ 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 (GetUserId() == (Oid) dba);
}
diff --git a/src/include/catalog/pg_shadow.h b/src/include/catalog/pg_shadow.h
index e0b087a9d91..fdec3fa82ca 100644
--- a/src/include/catalog/pg_shadow.h
+++ b/src/include/catalog/pg_shadow.h
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_shadow.h,v 1.11 2001/03/09 22:10:13 tgl Exp $
+ * $Id: pg_shadow.h,v 1.12 2001/06/13 21:44:41 tgl Exp $
*
* NOTES
* the genbki.sh script reads this file and generates .bki
@@ -24,10 +24,6 @@
#define PG_SHADOW_H
-/* Prototype required for superuser() from superuser.c */
-
-bool superuser(void);
-
/* ----------------
* pg_shadow definition. cpp turns this into
* typedef struct FormData_pg_shadow
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 742f58137c5..588c2f99dea 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: miscadmin.h,v 1.85 2001/05/12 01:48:49 petere Exp $
+ * $Id: miscadmin.h,v 1.86 2001/06/13 21:44:41 tgl Exp $
*
* NOTES
* some of the information in this file should be moved to
@@ -220,9 +220,13 @@ extern int CheckPathAccess(char *path, char *name, int open_mode);
extern void GetCharSetByHost(char *TableName, int host, const char *DataDir);
extern void SetCharSet(void);
extern char *convertstr(unsigned char *buff, int len, int dest);
-
#endif
+/* in utils/misc/superuser.c */
+extern bool superuser(void); /* current user is superuser */
+extern bool is_dbadmin(Oid dbid); /* current user is owner of database */
+
+
/*****************************************************************************
* pmod.h -- *
* POSTGRES processing mode definitions. *