@@ -5012,6 +5012,60 @@ has_privs_of_role(Oid member, Oid role)
50125012}
50135013
50145014
5015+ // -- non-upstream patch begin
5016+ /*
5017+ * Is userId allowed to bypass ownership check
5018+ * and tranfer onwership to ownerId role?
5019+ */
5020+ bool
5021+ mdb_admin_allow_bypass_owner_checks (Oid userId , Oid ownerId )
5022+ {
5023+ Oid mdb_admin_roleoid ;
5024+ /*
5025+ * Never allow nobody to grant objects to
5026+ * superusers.
5027+ * This can result in various CVE.
5028+ * For paranoic reasons, check this even before
5029+ * membership of mdb_admin role.
5030+ */
5031+ if (superuser_arg (ownerId )) {
5032+ return false;
5033+ }
5034+
5035+ mdb_admin_roleoid = get_role_oid ("mdb_admin" , true /* superuser suggested to be mdb_admin*/ );
5036+ /* Is userId actually member of mdb admin? */
5037+ if (!is_member_of_role (userId , mdb_admin_roleoid )) {
5038+ /* if no, disallow. */
5039+ return false;
5040+ }
5041+
5042+ /*
5043+ * Now, we need to check if ownerId
5044+ * is some dangerous role to trasfer membership to.
5045+ *
5046+ * For now, we check that ownerId does not have
5047+ * priviledge to execute server program or/and
5048+ * read/write server files.
5049+ */
5050+
5051+ if (has_privs_of_role (ownerId , ROLE_PG_READ_SERVER_FILES )) {
5052+ return false;
5053+ }
5054+
5055+ if (has_privs_of_role (ownerId , ROLE_PG_WRITE_SERVER_FILES )) {
5056+ return false;
5057+ }
5058+
5059+ if (has_privs_of_role (ownerId , ROLE_PG_EXECUTE_SERVER_PROGRAM )) {
5060+ return false;
5061+ }
5062+
5063+ /* All checks passed, hope will not be hacked here (again) */
5064+ return true;
5065+ }
5066+
5067+ // -- non-upstream patch end
5068+
50155069/*
50165070 * Is member a member of role (directly or indirectly)?
50175071 *
@@ -5051,6 +5105,64 @@ check_is_member_of_role(Oid member, Oid role)
50515105 GetUserNameFromId (role , false))));
50525106}
50535107
5108+ // -- mdb admin patch
5109+ /*
5110+ * check_mdb_admin_is_member_of_role
5111+ * is_member_of_role with a standard permission-violation error if not in usual case
5112+ * Is case `member` in mdb_admin we check that role is neither of superuser, pg_read/write
5113+ * server files nor pg_execute_server_program
5114+ */
5115+ void
5116+ check_mdb_admin_is_member_of_role (Oid member , Oid role )
5117+ {
5118+ Oid mdb_admin_roleoid ;
5119+ /* fast path - if we are superuser, its ok */
5120+ if (superuser_arg (member )) {
5121+ return ;
5122+ }
5123+
5124+ mdb_admin_roleoid = get_role_oid ("mdb_admin" , true /* superuser suggested to be mdb_admin*/ );
5125+ /* Is userId actually member of mdb admin? */
5126+ if (is_member_of_role (member , mdb_admin_roleoid )) {
5127+ /* role is mdb admin */
5128+ if (superuser_arg (role )) {
5129+ ereport (ERROR ,
5130+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
5131+ errmsg ("cannot transfer ownership to superuser \"%s\"" ,
5132+ GetUserNameFromId (role , false))));
5133+ }
5134+
5135+ if (has_privs_of_role (role , ROLE_PG_READ_SERVER_FILES )) {
5136+ ereport (ERROR ,
5137+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
5138+ errmsg ("cannot transfer ownership to pg_read_server_files role in Cloud" )));
5139+ }
5140+
5141+ if (has_privs_of_role (role , ROLE_PG_WRITE_SERVER_FILES )) {
5142+ ereport (ERROR ,
5143+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
5144+ errmsg ("cannot transfer ownership to pg_write_server_files role in Cloud" )));
5145+ }
5146+
5147+ if (has_privs_of_role (role , ROLE_PG_EXECUTE_SERVER_PROGRAM )) {
5148+ ereport (ERROR ,
5149+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
5150+ errmsg ("cannot transfer ownership to pg_execute_server_program role in Cloud" )));
5151+ }
5152+ } else {
5153+ /* if no, check membership transfer in usual way. */
5154+
5155+ if (!is_member_of_role (member , role )) {
5156+ ereport (ERROR ,
5157+ (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
5158+ errmsg ("must be member of role \"%s\"" ,
5159+ GetUserNameFromId (role , false))));
5160+ }
5161+ }
5162+ }
5163+
5164+ // -- mdb admin patch
5165+
50545166/*
50555167 * Is member a member of role, not considering superuserness?
50565168 *
0 commit comments