diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-07-07 20:40:02 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-07-07 20:40:02 +0000 |
commit | 59d1b3d99e690734fa2a2bd0fae12b0cb1084294 (patch) | |
tree | ff074126ccc1a6342de38737d79e218f22fb9be4 /src/backend/commands | |
parent | 442b59dd8bc4b0efa1d733690f6ba9dae3f61b1f (diff) | |
download | postgresql-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.c | 7 | ||||
-rw-r--r-- | src/backend/commands/dbcommands.c | 18 | ||||
-rw-r--r-- | src/backend/commands/functioncmds.c | 5 | ||||
-rw-r--r-- | src/backend/commands/opclasscmds.c | 8 | ||||
-rw-r--r-- | src/backend/commands/operatorcmds.c | 5 | ||||
-rw-r--r-- | src/backend/commands/schemacmds.c | 6 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 5 | ||||
-rw-r--r-- | src/backend/commands/tablespace.c | 10 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 6 | ||||
-rw-r--r-- | src/backend/commands/user.c | 54 |
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 |