*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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();
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
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 ***/
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 ***/
heap_endscan(scan);
heap_close(pg_database, AccessShareLock);
-
}
/*------------------------------------------------------------------
*
*
* 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
*
*-------------------------------------------------------------------------
*/
+#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"
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
#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"
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,
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
* 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"
* 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
* 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
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
/*
* 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();
*
*
* 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
#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"
/*-------------------------------------------------------------------------
*
* 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()),
{
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);
}
* 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
#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
* 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
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. *