aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-07-07 20:40:02 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-07-07 20:40:02 +0000
commit59d1b3d99e690734fa2a2bd0fae12b0cb1084294 (patch)
treeff074126ccc1a6342de38737d79e218f22fb9be4 /src/backend/commands
parent442b59dd8bc4b0efa1d733690f6ba9dae3f61b1f (diff)
downloadpostgresql-59d1b3d99e690734fa2a2bd0fae12b0cb1084294.tar.gz
postgresql-59d1b3d99e690734fa2a2bd0fae12b0cb1084294.zip
Track dependencies on shared objects (which is to say, roles; we already
have adequate mechanisms for tracking the contents of databases and tablespaces). This solves the longstanding problem that you can drop a user who still owns objects and/or has access permissions. Alvaro Herrera, with some kibitzing from Tom Lane.
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/conversioncmds.c7
-rw-r--r--src/backend/commands/dbcommands.c18
-rw-r--r--src/backend/commands/functioncmds.c5
-rw-r--r--src/backend/commands/opclasscmds.c8
-rw-r--r--src/backend/commands/operatorcmds.c5
-rw-r--r--src/backend/commands/schemacmds.c6
-rw-r--r--src/backend/commands/tablecmds.c5
-rw-r--r--src/backend/commands/tablespace.c10
-rw-r--r--src/backend/commands/typecmds.c6
-rw-r--r--src/backend/commands/user.c54
10 files changed, 75 insertions, 49 deletions
diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c
index c2aa48614e6..9cc72ec7327 100644
--- a/src/backend/commands/conversioncmds.c
+++ b/src/backend/commands/conversioncmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.19 2005/06/28 05:08:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/conversioncmds.c,v 1.20 2005/07/07 20:39:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,6 +17,7 @@
#include "catalog/pg_conversion.h"
#include "access/heapam.h"
#include "catalog/catalog.h"
+#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
@@ -220,6 +221,10 @@ AlterConversionOwner(List *name, Oid newOwnerId)
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(ConversionRelationId, conversionOid,
+ newOwnerId);
}
heap_close(rel, NoLock);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index ba5ce9200b4..486afb2e21f 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.164 2005/06/30 00:00:50 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.165 2005/07/07 20:39:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -28,6 +28,7 @@
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/catalog.h"
+#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
@@ -511,6 +512,12 @@ createdb(const CreatedbStmt *stmt)
/* Update indexes */
CatalogUpdateIndexes(pg_database_rel, tuple);
+ /* Register owner dependency */
+ recordDependencyOnOwner(DatabaseRelationId, dboid, datdba);
+
+ /* Create pg_shdepend entries for objects within database */
+ copyTemplateDependencies(src_dboid, dboid);
+
/* Close pg_database, but keep exclusive lock till commit */
heap_close(pg_database_rel, NoLock);
@@ -680,6 +687,11 @@ dropdb(const char *dbname)
heap_close(pgdbrel, NoLock);
/*
+ * Remove shared dependency references for the database.
+ */
+ dropDatabaseDependencies(db_id);
+
+ /*
* Set flag to update flat database file at commit.
*/
database_file_update_needed();
@@ -951,6 +963,10 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(DatabaseRelationId, HeapTupleGetOid(tuple),
+ newOwnerId);
}
systable_endscan(scan);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 3329822fe62..8867538f8eb 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.62 2005/06/28 05:08:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.63 2005/07/07 20:39:58 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
@@ -925,6 +925,9 @@ AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId)
CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(ProcedureRelationId, procOid, newOwnerId);
}
ReleaseSysCache(tup);
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 3610269644a..a0d0abd553d 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.33 2005/06/28 05:08:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.34 2005/07/07 20:39:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -392,6 +392,9 @@ DefineOpClass(CreateOpClassStmt *stmt)
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
+ /* dependency on owner */
+ recordDependencyOnOwner(OperatorClassRelationId, opclassoid, GetUserId());
+
heap_close(rel, RowExclusiveLock);
}
@@ -962,6 +965,9 @@ AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId)
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(OperatorClassRelationId, amOid, newOwnerId);
}
heap_close(rel, NoLock);
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index adea1b2b5d7..ae93e9230ee 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.22 2005/06/28 05:08:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/operatorcmds.c,v 1.23 2005/07/07 20:39:58 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -310,6 +310,9 @@ AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2,
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(OperatorRelationId, operOid, newOwnerId);
}
heap_close(rel, NoLock);
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index d92812f1fcf..c4c20ddeb39 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.31 2005/06/28 05:08:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.32 2005/07/07 20:39:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -342,6 +342,10 @@ AlterSchemaOwner(const char *name, Oid newOwnerId)
CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(NamespaceRelationId, HeapTupleGetOid(tup),
+ newOwnerId);
}
ReleaseSysCache(tup);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index dda9532baf8..2b50a402fc8 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.162 2005/06/28 05:08:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.163 2005/07/07 20:39:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -5321,6 +5321,9 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId)
heap_freetuple(newtuple);
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(RelationRelationId, relationOid, newOwnerId);
+
/*
* If we are operating on a table, also change the ownership of
* any indexes and sequences that belong to the table, as well as
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index b925825062f..a2cce14335c 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.24 2005/07/04 04:51:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.25 2005/07/07 20:39:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,6 +50,7 @@
#include "access/heapam.h"
#include "catalog/catalog.h"
+#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
@@ -307,6 +308,9 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
heap_freetuple(tuple);
+ /* Record dependency on owner */
+ recordDependencyOnOwner(TableSpaceRelationId, tablespaceoid, ownerId);
+
/*
* Attempt to coerce target directory to safe permissions. If this
* fails, it doesn't exist or has the wrong owner.
@@ -818,6 +822,10 @@ AlterTableSpaceOwner(const char *name, Oid newOwnerId)
CatalogUpdateIndexes(rel, newtuple);
heap_freetuple(newtuple);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(TableSpaceRelationId, HeapTupleGetOid(tup),
+ newOwnerId);
}
heap_endscan(scandesc);
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 53570c77409..e5f2a2f762b 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.73 2005/06/28 05:08:54 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.74 2005/07/07 20:39:58 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -1208,6 +1208,7 @@ AlterDomainDefault(List *names, Node *defaultRaw)
domainoid,
typTup->typrelid,
0, /* relation kind is n/a */
+ typTup->typowner,
typTup->typinput,
typTup->typoutput,
typTup->typreceive,
@@ -2080,6 +2081,9 @@ AlterTypeOwner(List *names, Oid newOwnerId)
simple_heap_update(rel, &tup->t_self, tup);
CatalogUpdateIndexes(rel, tup);
+
+ /* Update owner dependency reference */
+ changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId);
}
/* Clean up */
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 982c286cde7..4a46343d5d8 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.155 2005/06/29 20:34:13 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.156 2005/07/07 20:39:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -14,10 +14,10 @@
#include "access/genam.h"
#include "access/heapam.h"
+#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
-#include "catalog/pg_database.h"
#include "commands/user.h"
#include "libpq/crypt.h"
#include "miscadmin.h"
@@ -742,10 +742,8 @@ DropRole(DropRoleStmt *stmt)
const char *role = strVal(lfirst(item));
HeapTuple tuple,
tmp_tuple;
- Relation pg_rel;
- TupleDesc pg_dsc;
- ScanKeyData scankey;
- HeapScanDesc scan;
+ ScanKeyData scankey;
+ char *detail;
SysScanDesc sscan;
Oid roleid;
@@ -780,42 +778,18 @@ DropRole(DropRoleStmt *stmt)
errmsg("must be superuser to drop superusers")));
/*
- * Check if role still owns a database. If so, error out.
- *
- * (It used to be that this function would drop the database
- * automatically. This is not only very dangerous for people that
- * don't read the manual, it doesn't seem to be the behaviour one
- * would expect either.) -- petere 2000/01/14)
- */
- pg_rel = heap_open(DatabaseRelationId, AccessShareLock);
- pg_dsc = RelationGetDescr(pg_rel);
-
- ScanKeyInit(&scankey,
- Anum_pg_database_datdba,
- BTEqualStrategyNumber, F_OIDEQ,
- roleid);
-
- scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey);
-
- if ((tmp_tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
- {
- char *dbname;
+ * Lock the role, so nobody can add dependencies to her while we drop
+ * her. We keep the lock until the end of transaction.
+ */
+ LockSharedObject(AuthIdRelationId, roleid, 0, AccessExclusiveLock);
- dbname = NameStr(((Form_pg_database) GETSTRUCT(tmp_tuple))->datname);
+ /* Check for pg_shdepend entries depending on this role */
+ if ((detail = checkSharedDependencies(AuthIdRelationId, roleid)) != NULL)
ereport(ERROR,
- (errcode(ERRCODE_OBJECT_IN_USE),
- errmsg("role \"%s\" cannot be dropped", role),
- errdetail("The role owns database \"%s\".", dbname)));
- }
-
- heap_endscan(scan);
- heap_close(pg_rel, AccessShareLock);
-
- /*
- * Somehow we'd have to check for tables, views, etc. owned by the
- * role as well, but those could be spread out over all sorts of
- * databases which we don't have access to (easily).
- */
+ (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
+ errmsg("role \"%s\" cannot be dropped because some objects depend on it",
+ role),
+ errdetail("%s", detail)));
/*
* Remove the role from the pg_authid table