aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/schemacmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/schemacmds.c')
-rw-r--r--src/backend/commands/schemacmds.c80
1 files changed, 44 insertions, 36 deletions
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index c4c20ddeb39..65a6edeabc7 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.32 2005/07/07 20:39:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.33 2005/07/14 21:46:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -49,54 +49,45 @@ CreateSchemaCommand(CreateSchemaStmt *stmt)
saved_uid = GetUserId();
/*
- * Figure out user identities.
+ * Who is supposed to own the new schema?
*/
-
- if (!authId)
- {
- owner_uid = saved_uid;
- }
- else if (superuser())
- {
+ if (authId)
owner_uid = get_roleid_checked(authId);
-
- /*
- * Set the current user to the requested authorization so that
- * objects created in the statement have the requested owner.
- * (This will revert to session user on error or at the end of
- * this routine.)
- */
- SetUserId(owner_uid);
- }
else
- {
- const char *owner_name;
-
- /* not superuser */
owner_uid = saved_uid;
- owner_name = GetUserNameFromId(owner_uid);
- if (strcmp(authId, owner_name) != 0)
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("permission denied"),
- errdetail("\"%s\" is not a superuser, so cannot create a schema for \"%s\"",
- owner_name, authId)));
- }
/*
- * Permissions checks.
+ * To create a schema, must have schema-create privilege on the current
+ * database and must be able to become the target role (this does not
+ * imply that the target role itself must have create-schema privilege).
+ * The latter provision guards against "giveaway" attacks. Note that
+ * a superuser will always have both of these privileges a fortiori.
*/
aclresult = pg_database_aclcheck(MyDatabaseId, saved_uid, ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, ACL_KIND_DATABASE,
get_database_name(MyDatabaseId));
+ check_is_member_of_role(saved_uid, owner_uid);
+
+ /* Additional check to protect reserved schema names */
if (!allowSystemTableMods && IsReservedName(schemaName))
ereport(ERROR,
(errcode(ERRCODE_RESERVED_NAME),
errmsg("unacceptable schema name \"%s\"", schemaName),
errdetail("The prefix \"pg_\" is reserved for system schemas.")));
+ /*
+ * If the requested authorization is different from the current user,
+ * temporarily set the current user so that the object(s) will be
+ * created with the correct ownership.
+ *
+ * (The setting will revert to session user on error or at the end of
+ * this routine.)
+ */
+ if (saved_uid != owner_uid)
+ SetUserId(owner_uid);
+
/* Create the schema's namespace */
namespaceId = NamespaceCreate(schemaName, owner_uid);
@@ -308,12 +299,29 @@ AlterSchemaOwner(const char *name, Oid newOwnerId)
Datum aclDatum;
bool isNull;
HeapTuple newtuple;
+ AclResult aclresult;
+
+ /* Otherwise, must be owner of the existing object */
+ if (!pg_namespace_ownercheck(HeapTupleGetOid(tup),GetUserId()))
+ aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_NAMESPACE,
+ name);
+
+ /* Must be able to become new owner */
+ check_is_member_of_role(GetUserId(),newOwnerId);
- /* Otherwise, must be superuser to change object ownership */
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("must be superuser to change owner")));
+ /*
+ * must have create-schema rights
+ *
+ * NOTE: This is different from other alter-owner checks in
+ * that the current user is checked for create privileges
+ * instead of the destination owner. This is consistent
+ * with the CREATE case for schemas.
+ */
+ aclresult = pg_database_aclcheck(MyDatabaseId, GetUserId(),
+ ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, ACL_KIND_DATABASE,
+ get_database_name(MyDatabaseId));
memset(repl_null, ' ', sizeof(repl_null));
memset(repl_repl, ' ', sizeof(repl_repl));