aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/user.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/user.c')
-rw-r--r--src/backend/commands/user.c82
1 files changed, 38 insertions, 44 deletions
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 4d193a6f9a4..3a92e930c06 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -311,33 +311,28 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
bypassrls = boolVal(dbypassRLS->arg);
/* Check some permissions first */
- if (issuper)
+ if (!superuser_arg(currentUserId))
{
- if (!superuser())
+ if (!has_createrole_privilege(currentUserId))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("permission denied to create role")));
+ if (issuper)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to create superusers")));
- }
- else if (isreplication)
- {
- if (!superuser())
+ if (createdb && !have_createdb_privilege())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to create replication users")));
- }
- else if (bypassrls)
- {
- if (!superuser())
+ errmsg("must have createdb permission to create createdb users")));
+ if (isreplication && !has_rolreplication(currentUserId))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to create bypassrls users")));
- }
- else
- {
- if (!have_createrole_privilege())
+ errmsg("must have replication permission to create replication users")));
+ if (bypassrls && !has_bypassrls_privilege(currentUserId))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("permission denied to create role")));
+ errmsg("must have bypassrls to create bypassrls users")));
}
/*
@@ -748,32 +743,11 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
rolename = pstrdup(NameStr(authform->rolname));
roleid = authform->oid;
- /*
- * To mess with a superuser or replication role in any way you gotta be
- * superuser. We also insist on superuser to change the BYPASSRLS
- * property.
- */
- if (authform->rolsuper || dissuper)
- {
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to alter superuser roles or change superuser attribute")));
- }
- else if (authform->rolreplication || disreplication)
- {
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to alter replication roles or change replication attribute")));
- }
- else if (dbypassRLS)
- {
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to change bypassrls attribute")));
- }
+ /* To mess with a superuser in any way you gotta be superuser. */
+ if (!superuser() && (authform->rolsuper || dissuper))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must be superuser to alter superuser roles or change superuser attribute")));
/*
* Most changes to a role require that you both have CREATEROLE privileges
@@ -784,7 +758,7 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
{
/* things an unprivileged user certainly can't do */
if (dinherit || dcreaterole || dcreatedb || dcanlogin || dconnlimit ||
- dvalidUntil)
+ dvalidUntil || disreplication || dbypassRLS)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied")));
@@ -795,6 +769,26 @@ AlterRole(ParseState *pstate, AlterRoleStmt *stmt)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must have CREATEROLE privilege to change another user's password")));
}
+ else if (!superuser())
+ {
+ /*
+ * Even if you have both CREATEROLE and ADMIN OPTION on a role, you
+ * can only change the CREATEDB, REPLICATION, or BYPASSRLS attributes
+ * if they are set for your own role (or you are the superuser).
+ */
+ if (dcreatedb && !have_createdb_privilege())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must have createdb privilege to change createdb attribute")));
+ if (disreplication && !has_rolreplication(currentUserId))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must have replication privilege to change replication attribute")));
+ if (dbypassRLS && !has_bypassrls_privilege(currentUserId))
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ errmsg("must have bypassrls privilege to change bypassrls attribute")));
+ }
/* To add members to a role, you need ADMIN OPTION. */
if (drolemembers && !is_admin_of_role(currentUserId, roleid))