fix reassign issue of directory.

This commit is contained in:
gentle_hu
2022-09-13 14:27:48 +08:00
parent 8529e7d6ab
commit 132a8a54ec
5 changed files with 127 additions and 60 deletions

View File

@ -57,6 +57,7 @@
#include "commands/sec_rls_cmds.h"
#include "commands/tablecmds.h"
#include "commands/typecmds.h"
#include "commands/directory.h"
#include "storage/lmgr.h"
#include "miscadmin.h"
#include "utils/acl.h"
@ -1412,6 +1413,10 @@ void shdepReassignOwned(List* roleids, Oid newrole)
AlterSubscriptionOwner_oid(sdepForm->objid, newrole);
break;
case PgDirectoryRelationId:
AlterPgDirectoryOwner_oid(sdepForm->objid, newrole);
break;
default:
ereport(ERROR,
(errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE), errmsg("unexpected classid %u", sdepForm->classid)));

View File

@ -389,37 +389,18 @@ void RemoveDirectoryById(Oid dirOid)
heap_close(relation, RowExclusiveLock);
}
/*
* ALTER Directory name OWNER TO newowner
*/
void AlterDirectoryOwner(const char* dirname, Oid newOwnerId)
static void AlterPgDirectoryOwner_internal(Relation rel, HeapTuple tuple, Oid newOwnerId)
{
HeapTuple tuple = NULL;
Relation rel;
ScanKeyData scankey;
SysScanDesc scan = NULL;
Form_pg_directory dirForm = NULL;
/*
* Get the old tuple. We don't need a lock on the directory per se,
* because we're not going to do anything that would mess up incoming
* connections.
*/
rel = heap_open(PgDirectoryRelationId, RowExclusiveLock);
ScanKeyInit(&scankey, Anum_pg_directory_directory_name, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(dirname));
scan = systable_beginscan(rel, PgDirectoryDirectoriesNameIndexId, true, NULL, 1, &scankey);
tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) {
heap_close(rel, RowExclusiveLock);
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("directory \"%s\" does not exist", dirname)));
}
dirForm = (Form_pg_directory)GETSTRUCT(tuple);
Form_pg_directory dirForm = (Form_pg_directory)GETSTRUCT(tuple);
/*
* If the new owner is the same as the existing owner, consider the
* command to have succeeded. This is to be consistent with other
* objects.
*/
if (dirForm->owner != newOwnerId) {
if (dirForm->owner == newOwnerId) {
return;
}
Datum repl_val[Natts_pg_directory];
bool repl_null[Natts_pg_directory];
bool repl_repl[Natts_pg_directory];
@ -432,7 +413,7 @@ void AlterDirectoryOwner(const char* dirname, Oid newOwnerId)
if (u_sess->attr.attr_storage.enable_access_server_directory) {
/* must be sysadmin or owner of the existing object */
if (!superuser() && !pg_directory_ownercheck(HeapTupleGetOid(tuple), GetUserId())) {
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DIRECTORY, dirname);
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DIRECTORY, NameStr(dirForm->dirname));
}
} else {
if (!initialuser()) {
@ -474,8 +455,53 @@ void AlterDirectoryOwner(const char* dirname, Oid newOwnerId)
changeDependencyOnOwner(PgDirectoryRelationId, HeapTupleGetOid(tuple), newOwnerId);
}
/*
* ALTER Directory name OWNER TO newowner
*/
void AlterDirectoryOwner(const char* dirname, Oid newOwnerId)
{
HeapTuple tuple = NULL;
Relation rel;
ScanKeyData scankey;
SysScanDesc scan = NULL;
/*
* Get the old tuple. We don't need a lock on the directory per se,
* because we're not going to do anything that would mess up incoming
* connections.
*/
rel = heap_open(PgDirectoryRelationId, RowExclusiveLock);
ScanKeyInit(&scankey, Anum_pg_directory_directory_name, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(dirname));
scan = systable_beginscan(rel, PgDirectoryDirectoriesNameIndexId, true, NULL, 1, &scankey);
tuple = systable_getnext(scan);
if (!HeapTupleIsValid(tuple)) {
heap_close(rel, RowExclusiveLock);
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("directory \"%s\" does not exist", dirname)));
}
AlterPgDirectoryOwner_internal(rel, tuple, newOwnerId);
systable_endscan(scan);
/* Close pg_database, but keep lock till commit */
heap_close(rel, NoLock);
}
void AlterPgDirectoryOwner_oid(Oid dirOid, Oid newOwnerId)
{
Relation rel;
HeapTuple tup = NULL;
rel = heap_open(PgDirectoryRelationId, RowExclusiveLock);
tup = SearchSysCacheCopy1(DIRECTORYOID, ObjectIdGetDatum(dirOid));
if (!HeapTupleIsValid(tup)) /* should not happen */
ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for directory %u", dirOid)));
AlterPgDirectoryOwner_internal(rel, tup, newOwnerId);
heap_freetuple(tup);
heap_close(rel, NoLock);
}

View File

@ -35,5 +35,6 @@ extern Oid get_directory_oid(const char* directoryname, bool missing_ok);
extern char* get_directory_name(Oid dir_oid);
extern void RemoveDirectoryById(Oid dirOid);
extern void AlterDirectoryOwner(const char* dirname, Oid newOwnerId);
extern void AlterPgDirectoryOwner_oid(Oid dirOid, Oid newOwnerId);
#endif /* DIRECTORY_H*/

View File

@ -133,5 +133,19 @@ DROP DIRECTORY test_dir2;
\! @abs_bindir@/gs_guc reload -Z datanode -D @abs_srcdir@/tmp_check/datanode1 -c "enable_access_server_directory=off" >/dev/null 2>&1
RESET ROLE;
alter system set enable_access_server_directory=on;
create user u_reassign_owned_0008_1 sysadmin password 'test@123';
create user u_reassign_owned_0008_2 sysadmin password 'test@123';
SET ROLE u_reassign_owned_0008_1 PASSWORD 'test@123';
show enable_access_server_directory;
create or replace directory dir_object_reassign_owned_0008 as '/tmp';
select t1.dirname, t2.usename, t1.dirpath from pg_directory t1 inner join pg_user t2 on t2.usesysid=t1.owner where t1.dirname='dir_object_reassign_owned_0008';
reassign owned by u_reassign_owned_0008_1 to u_reassign_owned_0008_2;
RESET ROLE;
alter system set enable_access_server_directory=off;
DROP USER test_user1,test_user2,test_user3;
DROP USER test_sysadmin,test_create,test_drop;
DROP USER u_reassign_owned_0008_1, u_reassign_owned_0008_2 cascade;

View File

@ -265,5 +265,26 @@ DROP DIRECTORY test_dir2;
\! rm -rf @testtablespace@/dir2
\! @abs_bindir@/gs_guc reload -Z datanode -D @abs_srcdir@/tmp_check/datanode1 -c "enable_access_server_directory=off" >/dev/null 2>&1
RESET ROLE;
alter system set enable_access_server_directory=on;
create user u_reassign_owned_0008_1 sysadmin password 'test@123';
create user u_reassign_owned_0008_2 sysadmin password 'test@123';
SET ROLE u_reassign_owned_0008_1 PASSWORD 'test@123';
show enable_access_server_directory;
enable_access_server_directory
--------------------------------
on
(1 row)
create or replace directory dir_object_reassign_owned_0008 as '/tmp';
select t1.dirname, t2.usename, t1.dirpath from pg_directory t1 inner join pg_user t2 on t2.usesysid=t1.owner where t1.dirname='dir_object_reassign_owned_0008';
dirname | usename | dirpath
--------------------------------+-------------------------+---------
dir_object_reassign_owned_0008 | u_reassign_owned_0008_1 | /tmp
(1 row)
reassign owned by u_reassign_owned_0008_1 to u_reassign_owned_0008_2;
RESET ROLE;
alter system set enable_access_server_directory=off;
DROP USER test_user1,test_user2,test_user3;
DROP USER test_sysadmin,test_create,test_drop;
DROP USER u_reassign_owned_0008_1, u_reassign_owned_0008_2 cascade;