Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pIHgs-0000u9-Fe for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Jan 2023 23:17:58 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1pIHgq-0007BB-Ui for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Jan 2023 23:17:56 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1pIHgq-0007B2-Ff for pgsql-hackers@lists.postgresql.org; Wed, 18 Jan 2023 23:17:56 +0000 Received: from mail-pj1-x1031.google.com ([2607:f8b0:4864:20::1031]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1pIHgn-0004HS-IQ for pgsql-hackers@postgresql.org; Wed, 18 Jan 2023 23:17:55 +0000 Received: by mail-pj1-x1031.google.com with SMTP id dw9so613222pjb.5 for ; Wed, 18 Jan 2023 15:17:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=mBDGKYt2AGygdyLPkzJ83BJIbeCvTX++dhV6SiNY1DA=; b=A3KWfRXPoXg+cZrJiKcduihhW2150q17WnFqDN8OC95kNjoEA+G5tJ8XOR9/y+NMLX 6HJWbf4XB+GXTmf3Elhr9W2ZCGj0gAw4Fks5AG+B3DwqPqSjgi71nZL3JnrcUgwcEgUk BwbvyIMK6DbxSzRMF8TIJoGIzzdUi4cbcYUWa7UVG972zJQVIRoyCjqhahkhUZ7DKQad Ylg5I+WFdbLKJmT6KrRTBjPOMGo2JhGLJRi3mXOnV6kcXHWjUoDaIGJQ96/3E3+LUktv e5HLZ1dsnRSCo7hQVZ2mQVd4iXtCbUWleXJD1bICNh+SXujdObt6Vv5JN8R9pvRQUY2M iZVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=mBDGKYt2AGygdyLPkzJ83BJIbeCvTX++dhV6SiNY1DA=; b=lp4d+mSGzeCsmFOWSPv7qW5zc7cmf9/I4MZt0aOjU+02UO2spKvQYWMvydmTqVwF6Q zADX2wfZcsKpOtOjkW+94NPHu9Xx/3P93lpcuLevQcYqRoSlAZeNi5p2AMSRQv2LGqJD CaD2esZvBJZ3IKpeyZEQBN4ipIKe3kXuOVGD4Y7VW03kJpvnAxejFobAF5sL1o+2Yygl LOC9SkCrrC2aLBKiGZLPIMK94gZyZiZdOqQGcsAQxH2xi5wXphJLCHpV2SV5iGciUM/O C2I+NMDyKvq6U+HQrWFaXQysWfJIT0YilLNM0uuMwiPqlVHZkh6sfylS/SY9DHeVfzMB GEEw== X-Gm-Message-State: AFqh2krqxta/26Q2If6kso1kb60mSaD5/ai8L8HjKd6HSWEa620382a0 1Lqn6T+DURigH0XoWl27zNE= X-Google-Smtp-Source: AMrXdXsanxkcMozVW8N1MogSa6sMHAH9ZUNKNWTkoYedUpT3D8mmfv/IschmNZL05kJM7NNa9HwPVQ== X-Received: by 2002:a17:902:b598:b0:194:645a:fa9a with SMTP id a24-20020a170902b59800b00194645afa9amr9078314pls.8.1674083872160; Wed, 18 Jan 2023 15:17:52 -0800 (PST) Received: from nathanxps13 ([50.47.162.83]) by smtp.gmail.com with ESMTPSA id p9-20020a170902780900b00188fc6766d6sm23558551pll.219.2023.01.18.15.17.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Jan 2023 15:17:51 -0800 (PST) Date: Wed, 18 Jan 2023 15:17:49 -0800 From: Nathan Bossart To: Robert Haas Cc: "pgsql-hackers@postgresql.org" Subject: Re: CREATEROLE users vs. role properties Message-ID: <20230118231749.GA3790025@nathanxps13> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, Jan 18, 2023 at 12:15:33PM -0500, Robert Haas wrote: > On Mon, Jan 16, 2023 at 2:29 PM Robert Haas wrote: >> 1. It's still possible for a CREATEROLE user to hand out role >> attributes that they don't possess. The new prohibitions in >> cf5eb37c5ee0cc54c80d95c1695d7fca1f7c68cb prevent a CREATEROLE user >> from handing out membership in a role on which they lack sufficient >> permissions, but they don't prevent a CREATEROLE user who lacks >> CREATEDB from creating a new user who does have CREATEDB. I think we >> should subject the CREATEDB, REPLICATION, and BYPASSRLS attributes to >> the same rule that we now use for role memberships: you've got to have >> the property in order to give it to someone else. In the case of >> CREATEDB, this would tighten the current rules, which allow you to >> give out CREATEDB without having it. In the case of REPLICATION and >> BYPASSRLS, this would liberalize the current rules: right now, a >> CREATEROLE user cannot give REPLICATION or BYPASSRLS to another user >> even if they possess those attributes. >> >> This proposal doesn't address the CREATEROLE or CONNECTION LIMIT >> properties. It seems possible to me that someone might want to set up >> a CREATEROLE user who can't make more such users, and this proposal >> doesn't manufacture any way of doing that. It also doesn't let you >> constraint the ability of a CREATEROLE user to set a CONNECTION LIMIT >> for some other user. I think that's OK. It might be nice to have ways >> of imposing such restrictions at some point in the future, but it is >> not very obvious what to do about such cases and, importantly, I don't >> think there's any security impact from failing to address those cases. >> If a CREATEROLE user without CREATEDB can create a new role that does >> have CREATEDB, that's a privilege escalation. If they can hand out >> CREATEROLE, that isn't: they already have it. > > Here is a patch implementing the above proposal. Since this is fairly > closely related to already-committed work, I would like to get this > into v16. That way, all the changes to how CREATEROLE works will go > into a single release, which seems less confusing for users. It is > also fairly clear to me that this is an improvement over the status > quo. Sometimes things that seem clear to me turn out to be false, so > if this change seems like a problem to you, please let me know. This seems like a clear improvement to me. However, as the attribute system becomes more sophisticated, I think we ought to improve the error messages in user.c. IMHO messages like "permission denied" could be greatly improved with some added context. For example, if I want to change a role's password, I need both CREATEROLE and ADMIN OPTION on the role, but the error message only mentions CREATEROLE. postgres=# create role createrole with createrole; CREATE ROLE postgres=# create role otherrole; CREATE ROLE postgres=# set role createrole; SET postgres=> alter role otherrole password 'test'; ERROR: must have CREATEROLE privilege to change another user's password Similarly, if I want to allow a role to grant REPLICATION to another role, I have to give it CREATEROLE, REPLICATION, and membership with ADMIN OPTION. If the role is missing CREATEROLE or membership with ADMIN OPTION, it'll only ever see a "permission denied" error. postgres=# create role createrole with createrole; CREATE ROLE postgres=# create role otherrole; CREATE ROLE postgres=# set role createrole; SET postgres=> alter role otherrole with replication; ERROR: permission denied postgres=> reset role; RESET postgres=# alter role createrole with replication; ALTER ROLE postgres=# set role createrole; SET postgres=> alter role otherrole with replication; ERROR: permission denied postgres=> reset role; RESET postgres=# grant otherrole to createrole; GRANT ROLE postgres=# set role createrole; SET postgres=> alter role otherrole with replication; ERROR: permission denied postgres=> reset role; RESET postgres=# grant otherrole to createrole with admin option; GRANT ROLE postgres=# set role createrole; SET postgres=> alter role otherrole with replication; ALTER ROLE If it has both CREATEROLE and membership with ADMIN OPTION (but not REPLICATION), it'll see a more helpful message. postgres=# create role createrole with createrole; CREATE ROLE postgres=# create role otherrole; CREATE ROLE postgres=# grant otherrole to createrole with admin option; GRANT ROLE postgres=# set role createrole; SET postgres=> alter role otherrole with replication; ERROR: must have replication privilege to change replication attribute This probably shouldn't block your patch, but I think it's worth doing in v16 since there are other changes in this area. I'm happy to help. -- Nathan Bossart Amazon Web Services: https://aws.amazon.com