!5739 新建用户不用赋权就可以lo_open管理员创建的大对象
Merge pull request !5739 from 雷紫薇/bug131572
This commit is contained in:
@ -82,6 +82,7 @@ Datum lo_open(PG_FUNCTION_ARGS)
|
||||
CreateFSContext();
|
||||
lobjDesc = inv_open(lobjId, mode, u_sess->libpq_cxt.fscxt);
|
||||
if (lobjDesc == NULL) { /* lookup failed */
|
||||
elog(DEBUG4, "could not open large object %u", lobjId);
|
||||
PG_RETURN_INT32(-1);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,21 @@ LargeObjectDesc* inv_open(Oid lobjId, int flags, MemoryContext mcxt)
|
||||
/* Can't use LargeObjectExists here because it always uses SnapshotNow */
|
||||
if (!myLargeObjectExists(lobjId, snapshot))
|
||||
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("large object %u does not exist", lobjId)));
|
||||
|
||||
|
||||
/* Apply permission checks, again specifying snapshot */
|
||||
if ((descflags & IFS_RDLOCK) != 0) {
|
||||
if (!u_sess->attr.attr_sql.lo_compat_privileges &&
|
||||
pg_largeobject_aclcheck_snapshot(lobjId, GetUserId(), ACL_SELECT, snapshot) != ACLCHECK_OK)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied for large object %u", lobjId)));
|
||||
}
|
||||
if ((descflags & IFS_WRLOCK) != 0) {
|
||||
if (!u_sess->attr.attr_sql.lo_compat_privileges &&
|
||||
pg_largeobject_aclcheck_snapshot(lobjId, GetUserId(), ACL_UPDATE, snapshot) != ACLCHECK_OK)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied for large object %u", lobjId)));
|
||||
}
|
||||
|
||||
/*
|
||||
* We must register the snapshot in TopTransaction's resowner, because
|
||||
* it must stay alive until the LO is closed rather than until the
|
||||
@ -542,7 +556,9 @@ int inv_write(LargeObjectDesc* obj_desc, const char* buf, int nbytes)
|
||||
Assert(buf != NULL);
|
||||
|
||||
/* enforce writability because snapshot is probably wrong otherwise */
|
||||
Assert(obj_desc->flags & IFS_WRLOCK);
|
||||
if ((obj_desc->flags & IFS_WRLOCK) == 0)
|
||||
ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied for large object %u", obj_desc->id)));
|
||||
|
||||
if (nbytes <= 0) {
|
||||
return 0;
|
||||
@ -722,7 +738,9 @@ void inv_truncate(LargeObjectDesc* obj_desc, int64 len)
|
||||
Assert(PointerIsValid(obj_desc));
|
||||
|
||||
/* enforce writability because snapshot is probably wrong otherwise */
|
||||
Assert(obj_desc->flags & IFS_WRLOCK);
|
||||
if ((obj_desc->flags & IFS_WRLOCK) == 0)
|
||||
ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied for large object %u", obj_desc->id)));
|
||||
|
||||
/*
|
||||
* use errmsg_internal here because we don't want to expose INT64_FORMAT
|
||||
|
51
src/test/regress/expected/large_object_permission.out
Normal file
51
src/test/regress/expected/large_object_permission.out
Normal file
@ -0,0 +1,51 @@
|
||||
create database large_object_test_db;
|
||||
\c large_object_test_db
|
||||
SELECT lo_create(100);
|
||||
lo_create
|
||||
-----------
|
||||
100
|
||||
(1 row)
|
||||
|
||||
CREATE USER u1 with password 'qwer@1234';
|
||||
CREATE USER u2 with password 'qwer@1234';
|
||||
GRANT SELECT ON LARGE OBJECT 100 to u1;
|
||||
SET SESSION AUTHORIZATION u1 PASSWORD 'qwer@1234';
|
||||
SELECT SESSION_USER, CURRENT_USER;
|
||||
session_user | current_user
|
||||
--------------+--------------
|
||||
u1 | u1
|
||||
(1 row)
|
||||
|
||||
select lo_open(100, CAST(x'20000' | x'40000' AS integer));
|
||||
ERROR: permission denied for large object 100
|
||||
CONTEXT: referenced column: lo_open
|
||||
select lo_open(100, CAST(x'40000' AS integer));
|
||||
lo_open
|
||||
---------
|
||||
0
|
||||
(1 row)
|
||||
|
||||
SET SESSION AUTHORIZATION u2 PASSWORD 'qwer@1234';
|
||||
SELECT SESSION_USER, CURRENT_USER;
|
||||
session_user | current_user
|
||||
--------------+--------------
|
||||
u2 | u2
|
||||
(1 row)
|
||||
|
||||
select lo_open(100, CAST(x'20000' | x'40000' AS integer));
|
||||
ERROR: permission denied for large object 100
|
||||
CONTEXT: referenced column: lo_open
|
||||
select lo_open(100, CAST(x'40000' AS integer));
|
||||
ERROR: permission denied for large object 100
|
||||
CONTEXT: referenced column: lo_open
|
||||
\c regression
|
||||
reset session AUTHORIZATION;
|
||||
SELECT SESSION_USER, CURRENT_USER;
|
||||
session_user | current_user
|
||||
--------------+--------------
|
||||
--?.*
|
||||
(1 row)
|
||||
|
||||
drop database large_object_test_db;
|
||||
drop user u1;
|
||||
drop user u2;
|
@ -295,7 +295,7 @@ test: plpgsql_reset_session plpgsql_nested_array_and_record
|
||||
#test: plpgsql_depend
|
||||
test: plpgsql_depend/plpgsql_depend_type plpgsql_depend/plpgsql_pkg_dependency plpgsql_depend/plpgsql_recompile plpgsql_depend/plpgsql_pkg_variable_dependency plpgsql_depend/plpgsql_depend_reftype
|
||||
#test: plancache limit rangefuncs prepare
|
||||
test: returning largeobject
|
||||
test: returning largeobject large_object_permission
|
||||
test: hw_explain_pretty1 hw_explain_pretty2 hw_explain_pretty3
|
||||
test: goto
|
||||
test: equivalence_class
|
||||
|
22
src/test/regress/sql/large_object_permission.sql
Normal file
22
src/test/regress/sql/large_object_permission.sql
Normal file
@ -0,0 +1,22 @@
|
||||
create database large_object_test_db;
|
||||
\c large_object_test_db
|
||||
SELECT lo_create(100);
|
||||
CREATE USER u1 with password 'qwer@1234';
|
||||
CREATE USER u2 with password 'qwer@1234';
|
||||
GRANT SELECT ON LARGE OBJECT 100 to u1;
|
||||
SET SESSION AUTHORIZATION u1 PASSWORD 'qwer@1234';
|
||||
SELECT SESSION_USER, CURRENT_USER;
|
||||
select lo_open(100, CAST(x'20000' | x'40000' AS integer));
|
||||
select lo_open(100, CAST(x'40000' AS integer));
|
||||
SET SESSION AUTHORIZATION u2 PASSWORD 'qwer@1234';
|
||||
SELECT SESSION_USER, CURRENT_USER;
|
||||
select lo_open(100, CAST(x'20000' | x'40000' AS integer));
|
||||
select lo_open(100, CAST(x'40000' AS integer));
|
||||
|
||||
\c regression
|
||||
reset session AUTHORIZATION;
|
||||
SELECT SESSION_USER, CURRENT_USER;
|
||||
drop database large_object_test_db;
|
||||
drop user u1;
|
||||
drop user u2;
|
||||
|
Reference in New Issue
Block a user