mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
REASSIGN OWNED: Support foreign data wrappers and servers
This was overlooked when implementing those kinds of objects, in commit cae565e503c42a0942ca1771665243b4453c5770. Per report from Pawel Casperek.
This commit is contained in:
parent
593a9631a7
commit
a417f85e1d
@ -25,6 +25,8 @@
|
|||||||
#include "catalog/pg_conversion.h"
|
#include "catalog/pg_conversion.h"
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "catalog/pg_default_acl.h"
|
#include "catalog/pg_default_acl.h"
|
||||||
|
#include "catalog/pg_foreign_data_wrapper.h"
|
||||||
|
#include "catalog/pg_foreign_server.h"
|
||||||
#include "catalog/pg_language.h"
|
#include "catalog/pg_language.h"
|
||||||
#include "catalog/pg_largeobject.h"
|
#include "catalog/pg_largeobject.h"
|
||||||
#include "catalog/pg_namespace.h"
|
#include "catalog/pg_namespace.h"
|
||||||
@ -1382,6 +1384,14 @@ shdepReassignOwned(List *roleids, Oid newrole)
|
|||||||
AlterOpFamilyOwner_oid(sdepForm->objid, newrole);
|
AlterOpFamilyOwner_oid(sdepForm->objid, newrole);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ForeignServerRelationId:
|
||||||
|
AlterForeignServerOwner_oid(sdepForm->objid, newrole);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ForeignDataWrapperRelationId:
|
||||||
|
AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "unexpected classid %u", sdepForm->classid);
|
elog(ERROR, "unexpected classid %u", sdepForm->classid);
|
||||||
break;
|
break;
|
||||||
|
@ -277,27 +277,24 @@ RenameForeignServer(const char *oldname, const char *newname)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change foreign-data wrapper owner.
|
* Internal workhorse for changing a data wrapper's owner.
|
||||||
*
|
*
|
||||||
* Allow this only for superusers; also the new owner must be a
|
* Allow this only for superusers; also the new owner must be a
|
||||||
* superuser.
|
* superuser.
|
||||||
*/
|
*/
|
||||||
void
|
static void
|
||||||
AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
|
AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
|
||||||
{
|
{
|
||||||
HeapTuple tup;
|
|
||||||
Relation rel;
|
|
||||||
Oid fdwId;
|
|
||||||
Form_pg_foreign_data_wrapper form;
|
Form_pg_foreign_data_wrapper form;
|
||||||
|
|
||||||
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
|
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
|
||||||
|
|
||||||
/* Must be a superuser to change a FDW owner */
|
/* Must be a superuser to change a FDW owner */
|
||||||
if (!superuser())
|
if (!superuser())
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
|
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
|
||||||
name),
|
NameStr(form->fdwname)),
|
||||||
errhint("Must be superuser to change owner of a foreign-data wrapper.")));
|
errhint("Must be superuser to change owner of a foreign-data wrapper.")));
|
||||||
|
|
||||||
/* New owner must also be a superuser */
|
/* New owner must also be a superuser */
|
||||||
@ -305,19 +302,9 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
|
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
|
||||||
name),
|
NameStr(form->fdwname)),
|
||||||
errhint("The owner of a foreign-data wrapper must be a superuser.")));
|
errhint("The owner of a foreign-data wrapper must be a superuser.")));
|
||||||
|
|
||||||
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
|
|
||||||
|
|
||||||
if (!HeapTupleIsValid(tup))
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
||||||
errmsg("foreign-data wrapper \"%s\" does not exist", name)));
|
|
||||||
|
|
||||||
fdwId = HeapTupleGetOid(tup);
|
|
||||||
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
|
|
||||||
|
|
||||||
if (form->fdwowner != newOwnerId)
|
if (form->fdwowner != newOwnerId)
|
||||||
{
|
{
|
||||||
form->fdwowner = newOwnerId;
|
form->fdwowner = newOwnerId;
|
||||||
@ -327,38 +314,73 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
|
|||||||
|
|
||||||
/* Update owner dependency reference */
|
/* Update owner dependency reference */
|
||||||
changeDependencyOnOwner(ForeignDataWrapperRelationId,
|
changeDependencyOnOwner(ForeignDataWrapperRelationId,
|
||||||
fdwId,
|
HeapTupleGetOid(tup),
|
||||||
newOwnerId);
|
newOwnerId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change foreign-data wrapper owner -- by name
|
||||||
|
*
|
||||||
|
* Note restrictions in the "_internal" function, above.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
|
||||||
|
{
|
||||||
|
HeapTuple tup;
|
||||||
|
Relation rel;
|
||||||
|
|
||||||
|
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
|
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
|
||||||
|
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("foreign-data wrapper \"%s\" does not exist", name)));
|
||||||
|
|
||||||
|
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
|
||||||
|
|
||||||
heap_freetuple(tup);
|
heap_freetuple(tup);
|
||||||
|
|
||||||
heap_close(rel, RowExclusiveLock);
|
heap_close(rel, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change foreign server owner
|
* Change foreign-data wrapper owner -- by OID
|
||||||
|
*
|
||||||
|
* Note restrictions in the "_internal" function, above.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
AlterForeignServerOwner(const char *name, Oid newOwnerId)
|
AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId)
|
||||||
{
|
{
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
Relation rel;
|
Relation rel;
|
||||||
Oid srvId;
|
|
||||||
AclResult aclresult;
|
|
||||||
Form_pg_foreign_server form;
|
|
||||||
|
|
||||||
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
|
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
|
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fwdId));
|
||||||
|
|
||||||
if (!HeapTupleIsValid(tup))
|
if (!HeapTupleIsValid(tup))
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
errmsg("server \"%s\" does not exist", name)));
|
errmsg("foreign-data wrapper with OID \"%u\" does not exist", fwdId)));
|
||||||
|
|
||||||
|
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
|
||||||
|
|
||||||
|
heap_freetuple(tup);
|
||||||
|
|
||||||
|
heap_close(rel, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal workhorse for changing a foreign server's owner
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
|
||||||
|
{
|
||||||
|
Form_pg_foreign_server form;
|
||||||
|
|
||||||
srvId = HeapTupleGetOid(tup);
|
|
||||||
form = (Form_pg_foreign_server) GETSTRUCT(tup);
|
form = (Form_pg_foreign_server) GETSTRUCT(tup);
|
||||||
|
|
||||||
if (form->srvowner != newOwnerId)
|
if (form->srvowner != newOwnerId)
|
||||||
@ -366,10 +388,15 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
|
|||||||
/* Superusers can always do it */
|
/* Superusers can always do it */
|
||||||
if (!superuser())
|
if (!superuser())
|
||||||
{
|
{
|
||||||
|
Oid srvId;
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
|
srvId = HeapTupleGetOid(tup);
|
||||||
|
|
||||||
/* Must be owner */
|
/* Must be owner */
|
||||||
if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
|
if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
|
||||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
|
||||||
name);
|
NameStr(form->srvname));
|
||||||
|
|
||||||
/* Must be able to become new owner */
|
/* Must be able to become new owner */
|
||||||
check_is_member_of_role(GetUserId(), newOwnerId);
|
check_is_member_of_role(GetUserId(), newOwnerId);
|
||||||
@ -393,12 +420,57 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
|
|||||||
changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup),
|
changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup),
|
||||||
newOwnerId);
|
newOwnerId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change foreign server owner -- by name
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AlterForeignServerOwner(const char *name, Oid newOwnerId)
|
||||||
|
{
|
||||||
|
HeapTuple tup;
|
||||||
|
Relation rel;
|
||||||
|
|
||||||
|
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
|
tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
|
||||||
|
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("server \"%s\" does not exist", name)));
|
||||||
|
|
||||||
|
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
|
||||||
|
|
||||||
heap_freetuple(tup);
|
heap_freetuple(tup);
|
||||||
|
|
||||||
heap_close(rel, RowExclusiveLock);
|
heap_close(rel, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change foreign server owner -- by OID
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
|
||||||
|
{
|
||||||
|
HeapTuple tup;
|
||||||
|
Relation rel;
|
||||||
|
|
||||||
|
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
|
tup = SearchSysCacheCopy1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
|
||||||
|
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("server with OID \"%u\" does not exist", srvId)));
|
||||||
|
|
||||||
|
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
|
||||||
|
|
||||||
|
heap_freetuple(tup);
|
||||||
|
|
||||||
|
heap_close(rel, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert a handler function name passed from the parser to an Oid.
|
* Convert a handler function name passed from the parser to an Oid.
|
||||||
|
@ -149,7 +149,9 @@ extern List *deserialize_deflist(Datum txt);
|
|||||||
extern void RenameForeignServer(const char *oldname, const char *newname);
|
extern void RenameForeignServer(const char *oldname, const char *newname);
|
||||||
extern void RenameForeignDataWrapper(const char *oldname, const char *newname);
|
extern void RenameForeignDataWrapper(const char *oldname, const char *newname);
|
||||||
extern void AlterForeignServerOwner(const char *name, Oid newOwnerId);
|
extern void AlterForeignServerOwner(const char *name, Oid newOwnerId);
|
||||||
|
extern void AlterForeignServerOwner_oid(Oid , Oid newOwnerId);
|
||||||
extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId);
|
extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId);
|
||||||
|
extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId);
|
||||||
extern void CreateForeignDataWrapper(CreateFdwStmt *stmt);
|
extern void CreateForeignDataWrapper(CreateFdwStmt *stmt);
|
||||||
extern void AlterForeignDataWrapper(AlterFdwStmt *stmt);
|
extern void AlterForeignDataWrapper(AlterFdwStmt *stmt);
|
||||||
extern void RemoveForeignDataWrapperById(Oid fdwId);
|
extern void RemoveForeignDataWrapperById(Oid fdwId);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user