1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

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.
This commit is contained in:
Tom Lane
2005-07-07 20:40:02 +00:00
parent 442b59dd8b
commit 59d1b3d99e
38 changed files with 1842 additions and 85 deletions

View File

@@ -2,7 +2,7 @@
#
# Makefile for backend/catalog
#
# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.54 2005/06/28 05:08:52 tgl Exp $
# $PostgreSQL: pgsql/src/backend/catalog/Makefile,v 1.55 2005/07/07 20:39:57 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -12,7 +12,8 @@ include $(top_builddir)/src/Makefile.global
OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o \
pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_type.o
pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \
pg_type.o
BKIFILES = postgres.bki postgres.description
@@ -31,7 +32,7 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
pg_namespace.h pg_conversion.h pg_database.h \
pg_namespace.h pg_conversion.h pg_database.h pg_shdepend.h \
pg_authid.h pg_auth_members.h pg_tablespace.h pg_depend.h \
indexing.h \
)

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.114 2005/06/28 19:51:21 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.115 2005/07/07 20:39:57 tgl Exp $
*
* NOTES
* See acl.h.
@@ -19,6 +19,7 @@
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_auth_members.h"
@@ -252,6 +253,10 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
Datum values[Natts_pg_class];
char nulls[Natts_pg_class];
char replaces[Natts_pg_class];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
/* open pg_class */
relation = heap_open(RelationRelationId, RowExclusiveLock);
@@ -344,11 +349,19 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
/* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges,
grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls));
@@ -359,13 +372,19 @@ ExecuteGrantStmt_Relation(GrantStmt *stmt)
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
ReleaseSysCache(tuple);
simple_heap_update(relation, &newtuple->t_self, newtuple);
/* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(RelationRelationId, relOid,
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
ReleaseSysCache(tuple);
pfree(new_acl);
heap_close(relation, RowExclusiveLock);
@@ -422,6 +441,10 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
Datum values[Natts_pg_database];
char nulls[Natts_pg_database];
char replaces[Natts_pg_database];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
relation = heap_open(DatabaseRelationId, RowExclusiveLock);
ScanKeyInit(&entry[0],
@@ -503,11 +526,19 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
/* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges,
grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls));
@@ -523,6 +554,12 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
/* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple),
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
pfree(new_acl);
heap_endscan(scan);
@@ -580,6 +617,10 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
Datum values[Natts_pg_proc];
char nulls[Natts_pg_proc];
char replaces[Natts_pg_proc];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
oid = LookupFuncNameTypeNames(func->funcname, func->funcargs, false);
@@ -658,11 +699,19 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
/* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges,
grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls));
@@ -673,13 +722,19 @@ ExecuteGrantStmt_Function(GrantStmt *stmt)
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
ReleaseSysCache(tuple);
simple_heap_update(relation, &newtuple->t_self, newtuple);
/* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(ProcedureRelationId, oid,
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
ReleaseSysCache(tuple);
pfree(new_acl);
heap_close(relation, RowExclusiveLock);
@@ -734,6 +789,10 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
Datum values[Natts_pg_language];
char nulls[Natts_pg_language];
char replaces[Natts_pg_language];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
relation = heap_open(LanguageRelationId, RowExclusiveLock);
tuple = SearchSysCache(LANGNAME,
@@ -822,11 +881,19 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
/* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges,
grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls));
@@ -837,13 +904,19 @@ ExecuteGrantStmt_Language(GrantStmt *stmt)
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
ReleaseSysCache(tuple);
simple_heap_update(relation, &newtuple->t_self, newtuple);
/* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple),
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
ReleaseSysCache(tuple);
pfree(new_acl);
heap_close(relation, RowExclusiveLock);
@@ -898,6 +971,10 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
Datum values[Natts_pg_namespace];
char nulls[Natts_pg_namespace];
char replaces[Natts_pg_namespace];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
relation = heap_open(NamespaceRelationId, RowExclusiveLock);
tuple = SearchSysCache(NAMESPACENAME,
@@ -977,11 +1054,19 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
/* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges,
grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls));
@@ -992,13 +1077,19 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
newtuple = heap_modifytuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
ReleaseSysCache(tuple);
simple_heap_update(relation, &newtuple->t_self, newtuple);
/* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple),
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
ReleaseSysCache(tuple);
pfree(new_acl);
heap_close(relation, RowExclusiveLock);
@@ -1055,6 +1146,10 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
Datum values[Natts_pg_tablespace];
char nulls[Natts_pg_tablespace];
char replaces[Natts_pg_tablespace];
int noldmembers;
int nnewmembers;
Oid *oldmembers;
Oid *newmembers;
relation = heap_open(TableSpaceRelationId, RowExclusiveLock);
ScanKeyInit(&entry[0],
@@ -1136,11 +1231,19 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
/* get a detoasted copy of the ACL */
old_acl = DatumGetAclPCopy(aclDatum);
/*
* We need the members of both old and new ACLs so we can correct
* the shared dependency information.
*/
noldmembers = aclmembers(old_acl, &oldmembers);
new_acl = merge_acl_with_grant(old_acl, stmt->is_grant,
stmt->grant_option, stmt->behavior,
stmt->grantees, this_privileges,
grantorId, ownerId);
nnewmembers = aclmembers(new_acl, &newmembers);
/* finished building new ACL value, now insert it */
MemSet(values, 0, sizeof(values));
MemSet(nulls, ' ', sizeof(nulls));
@@ -1156,6 +1259,12 @@ ExecuteGrantStmt_Tablespace(GrantStmt *stmt)
/* keep the catalog indexes up to date */
CatalogUpdateIndexes(relation, newtuple);
/* Update the shared dependency ACL info */
updateAclDependencies(TableSpaceRelationId, HeapTupleGetOid(tuple),
ownerId, stmt->is_grant,
noldmembers, oldmembers,
nnewmembers, newmembers);
pfree(new_acl);
heap_endscan(scan);

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.44 2005/04/14 20:03:23 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.45 2005/07/07 20:39:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -22,9 +22,11 @@
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_attrdef.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_language.h"
#include "catalog/pg_namespace.h"
@@ -32,12 +34,15 @@
#include "catalog/pg_operator.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_rewrite.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_type.h"
#include "commands/comment.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/proclang.h"
#include "commands/schemacmds.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
#include "commands/typecmds.h"
#include "lib/stringinfo.h"
@@ -509,6 +514,7 @@ recursiveDeletion(const ObjectAddress *object,
break;
}
/* delete the pg_depend tuple */
simple_heap_delete(depRel, &tup->t_self);
}
@@ -584,6 +590,14 @@ recursiveDeletion(const ObjectAddress *object,
*/
DeleteComments(object->objectId, object->classId, object->objectSubId);
/*
* Delete shared dependency references related to this object.
* Sub-objects (columns) don't have dependencies on global objects,
* so skip them.
*/
if (object->objectSubId == 0)
deleteSharedDependencyRecordsFor(object->classId, object->objectId);
/*
* CommandCounterIncrement here to ensure that preceding changes are
* all visible.
@@ -1365,6 +1379,18 @@ getObjectClass(const ObjectAddress *object)
case NamespaceRelationId:
Assert(object->objectSubId == 0);
return OCLASS_SCHEMA;
case AuthIdRelationId:
Assert(object->objectSubId == 0);
return OCLASS_ROLE;
case DatabaseRelationId:
Assert(object->objectSubId == 0);
return OCLASS_DATABASE;
case TableSpaceRelationId:
Assert(object->objectSubId == 0);
return OCLASS_TBLSPACE;
}
/* shouldn't get here */
@@ -1680,6 +1706,37 @@ getObjectDescription(const ObjectAddress *object)
break;
}
case OCLASS_ROLE:
{
appendStringInfo(&buffer, _("role %s"),
GetUserNameFromId(object->objectId));
break;
}
case OCLASS_DATABASE:
{
char *datname;
datname = get_database_name(object->objectId);
if (!datname)
elog(ERROR, "cache lookup failed for database %u",
object->objectId);
appendStringInfo(&buffer, _("database %s"), datname);
break;
}
case OCLASS_TBLSPACE:
{
char *tblspace;
tblspace = get_tablespace_name(object->objectId);
if (!tblspace)
elog(ERROR, "cache lookup failed for tablespace %u",
object->objectId);
appendStringInfo(&buffer, _("tablespace %s"), tblspace);
break;
}
default:
appendStringInfo(&buffer, "unrecognized object %u %u %d",
object->classId,

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.285 2005/06/05 00:38:07 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.286 2005/07/07 20:39:57 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -755,6 +755,8 @@ heap_create_with_catalog(const char *relname,
* make a dependency link to force the relation to be deleted if its
* namespace is. Skip this in bootstrap mode, since we don't make
* dependencies while bootstrapping.
*
* Also make a dependency link to its owner.
*/
if (!IsBootstrapProcessingMode())
{
@@ -768,6 +770,8 @@ heap_create_with_catalog(const char *relname,
referenced.objectId = relnamespace;
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
recordDependencyOnOwner(RelationRelationId, new_rel_oid, GetUserId());
}
/*

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.24 2005/06/28 05:08:52 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_conversion.c,v 1.25 2005/07/07 20:39:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -120,6 +120,10 @@ ConversionCreate(const char *conname, Oid connamespace,
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
/* create dependency on owner */
recordDependencyOnOwner(ConversionRelationId, HeapTupleGetOid(tup),
conowner);
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);

View File

@@ -8,13 +8,14 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.14 2005/06/28 05:08:52 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_namespace.c,v 1.15 2005/07/07 20:39:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/heapam.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_namespace.h"
#include "utils/builtins.h"
@@ -72,5 +73,8 @@ NamespaceCreate(const char *nspName, Oid ownerId)
heap_close(nspdesc, RowExclusiveLock);
/* Record dependency on owner */
recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId);
return nspoid;
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.92 2005/06/28 05:08:52 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_operator.c,v 1.93 2005/07/07 20:39:57 tgl Exp $
*
* NOTES
* these routines moved here from commands/define.c and somewhat cleaned up.
@@ -889,6 +889,7 @@ makeOperatorDependencies(HeapTuple tuple)
/* In case we are updating a shell, delete any existing entries */
deleteDependencyRecordsFor(myself.classId, myself.objectId);
deleteSharedDependencyRecordsFor(myself.classId, myself.objectId);
/* Dependency on namespace */
if (OidIsValid(oper->oprnamespace))
@@ -962,4 +963,8 @@ makeOperatorDependencies(HeapTuple tuple)
referenced.objectSubId = 0;
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* Dependency on owner */
recordDependencyOnOwner(OperatorRelationId, HeapTupleGetOid(tuple),
oper->oprowner);
}

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.131 2005/06/28 19:51:21 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.132 2005/07/07 20:39:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -349,7 +349,10 @@ ProcedureCreate(const char *procedureName,
* existing function, first delete any existing pg_depend entries.
*/
if (is_update)
{
deleteDependencyRecordsFor(ProcedureRelationId, retval);
deleteSharedDependencyRecordsFor(ProcedureRelationId, retval);
}
myself.classId = ProcedureRelationId;
myself.objectId = retval;
@@ -382,6 +385,9 @@ ProcedureCreate(const char *procedureName,
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
}
/* dependency on owner */
recordDependencyOnOwner(ProcedureRelationId, retval, GetUserId());
heap_freetuple(tup);
heap_close(rel, RowExclusiveLock);

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.101 2005/06/28 05:08:52 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/pg_type.c,v 1.102 2005/07/07 20:39:57 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -75,7 +75,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
namestrcpy(&name, typeName);
values[i++] = NameGetDatum(&name); /* typname */
values[i++] = ObjectIdGetDatum(typeNamespace); /* typnamespace */
values[i++] = ObjectIdGetDatum(InvalidOid); /* typowner */
values[i++] = ObjectIdGetDatum(GetUserId()); /* typowner */
values[i++] = Int16GetDatum(0); /* typlen */
values[i++] = BoolGetDatum(false); /* typbyval */
values[i++] = CharGetDatum(0); /* typtype */
@@ -117,6 +117,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace)
typoid,
InvalidOid,
0,
GetUserId(),
InvalidOid,
InvalidOid,
InvalidOid,
@@ -330,6 +331,7 @@ TypeCreate(const char *typeName,
typeObjectId,
relationOid,
relationKind,
GetUserId(),
inputProcedure,
outputProcedure,
receiveProcedure,
@@ -365,6 +367,7 @@ GenerateTypeDependencies(Oid typeNamespace,
Oid relationOid, /* only for 'c'atalog
* types */
char relationKind, /* ditto */
Oid owner,
Oid inputProcedure,
Oid outputProcedure,
Oid receiveProcedure,
@@ -379,7 +382,10 @@ GenerateTypeDependencies(Oid typeNamespace,
referenced;
if (rebuild)
{
deleteDependencyRecordsFor(TypeRelationId, typeObjectId);
deleteSharedDependencyRecordsFor(TypeRelationId, typeObjectId);
}
myself.classId = TypeRelationId;
myself.objectId = typeObjectId;
@@ -485,6 +491,9 @@ GenerateTypeDependencies(Oid typeNamespace,
/* Normal dependency on the default expression. */
if (defaultExpr)
recordDependencyOnExpr(&myself, defaultExpr, NIL, DEPENDENCY_NORMAL);
/* Shared dependency on owner. */
recordDependencyOnOwner(TypeRelationId, typeObjectId, owner);
}
/*

View File

@@ -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);

View File

@@ -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);
@@ -679,6 +686,11 @@ dropdb(const char *dbname)
/* Close pg_database, but keep exclusive lock till commit */
heap_close(pgdbrel, NoLock);
/*
* Remove shared dependency references for the database.
*/
dropDatabaseDependencies(db_id);
/*
* Set flag to update flat database file at commit.
*/
@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);
* 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);
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;
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

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.117 2005/06/29 20:34:14 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/acl.c,v 1.118 2005/07/07 20:39:58 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -59,6 +59,7 @@ static void check_circularity(const Acl *old_acl, const AclItem *mod_aip,
Oid ownerId);
static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs,
Oid ownerId, DropBehavior behavior);
static int oidComparator(const void *arg1, const void *arg2);
static AclMode convert_priv_string(text *priv_type_text);
@@ -1052,6 +1053,86 @@ aclmask(const Acl *acl, Oid roleid, Oid ownerId,
}
/*
* aclmembers
* Find out all the roleids mentioned in an Acl.
* Note that we do not distinguish grantors from grantees.
*
* *roleids is set to point to a palloc'd array containing distinct OIDs
* in sorted order. The length of the array is the function result.
*/
int
aclmembers(const Acl *acl, Oid **roleids)
{
Oid *list;
const AclItem *acldat;
int i,
j,
k;
if (acl == NULL || ACL_NUM(acl) == 0)
{
*roleids = NULL;
return 0;
}
/* Allocate the worst-case space requirement */
list = palloc(ACL_NUM(acl) * 2 * sizeof(Oid));
acldat = ACL_DAT(acl);
/*
* Walk the ACL collecting mentioned RoleIds.
*/
j = 0;
for (i = 0; i < ACL_NUM(acl); i++)
{
const AclItem *ai = &acldat[i];
if (ai->ai_grantee != ACL_ID_PUBLIC)
list[j++] = ai->ai_grantee;
/* grantor is currently never PUBLIC, but let's check anyway */
if (ai->ai_grantor != ACL_ID_PUBLIC)
list[j++] = ai->ai_grantor;
}
/* Sort the array */
qsort(list, j, sizeof(Oid), oidComparator);
/* Remove duplicates from the array */
k = 0;
for (i = 1; i < j; i++)
{
if (list[k] != list[i])
list[++k] = list[i];
}
/*
* We could repalloc the array down to minimum size, but it's hardly
* worth it since it's only transient memory.
*/
*roleids = list;
return k + 1;
}
/*
* oidComparator
* qsort comparison function for Oids
*/
static int
oidComparator(const void *arg1, const void *arg2)
{
Oid oid1 = * (const Oid *) arg1;
Oid oid2 = * (const Oid *) arg2;
if (oid1 > oid2)
return 1;
if (oid1 < oid2)
return -1;
return 0;
}
/*
* aclinsert (exported function)
*/