From 71f1e973068aeb34e268bd85669d66adac122817 Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Tue, 22 Jun 2021 18:11:18 +0200 Subject: [PATCH 1/2] add grants after creating extensions --- pkg/cluster/database.go | 20 ++++++++++++++++++++ pkg/cluster/sync.go | 13 ++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/pkg/cluster/database.go b/pkg/cluster/database.go index ba4cf223a..e7f201d0c 100644 --- a/pkg/cluster/database.go +++ b/pkg/cluster/database.go @@ -56,6 +56,13 @@ const ( ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT EXECUTE ON FUNCTIONS TO "%s","%s"; ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT USAGE ON TYPES TO "%s","%s";` + extensionPostCreateSQL = ` + GRANT SELECT ON ALL TABLES IN SCHEMA "%s" TO "%s","%s"; + GRANT SELECT ON ALL SEQUENCES IN SCHEMA "%s" TO "%s","%s"; + GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA "%s" TO "%s","%s"; + GRANT USAGE, UPDATE ON ALL SEQUENCES IN SCHEMA "%s" TO "%s","%s"; + GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "%s" TO "%s","%s","%s";` + connectionPoolerLookup = ` CREATE SCHEMA IF NOT EXISTS {{.pooler_schema}}; @@ -418,6 +425,19 @@ func (c *Cluster) execAlterGlobalDefaultPrivileges(owner, rolePrefix string) err return nil } +func (c *Cluster) execExtensionPostCreatePrivileges(schemaName, rolePrefix string) error { + if _, err := c.pgDb.Exec(fmt.Sprintf(extensionPostCreateSQL, + schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.ReaderRoleNameSuffix, // tables + schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.ReaderRoleNameSuffix, // sequences + schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.WriterRoleNameSuffix, // tables + schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.WriterRoleNameSuffix, // sequences + schemaName, rolePrefix+constants.OwnerRoleNameSuffix, rolePrefix+constants.ReaderRoleNameSuffix, rolePrefix+constants.WriterRoleNameSuffix)); err != nil { // functions + return fmt.Errorf("could not set privileges in schema %s: %v", schemaName, err) + } + + return nil +} + func makeUserFlags(rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin bool) (result []string) { if rolsuper { result = append(result, constants.RoleFlagSuperuser) diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index 53552f558..2823870e3 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -386,7 +386,6 @@ func (c *Cluster) syncStatefulSet() error { return fmt.Errorf("could not set cluster-wide PostgreSQL configuration options: %v", err) } - if instancesRestartRequired { c.logger.Debugln("restarting Postgres server within pods") c.eventRecorder.Event(c.GetReference(), v1.EventTypeNormal, "Update", "restarting Postgres server within pods") @@ -769,7 +768,7 @@ func (c *Cluster) syncPreparedDatabases() error { } // install extensions - if err := c.syncExtensions(preparedDB.Extensions); err != nil { + if err := c.syncExtensions(preparedDbName, preparedDB.Extensions); err != nil { return err } @@ -813,7 +812,7 @@ func (c *Cluster) syncPreparedSchemas(databaseName string, preparedSchemas map[s return nil } -func (c *Cluster) syncExtensions(extensions map[string]string) error { +func (c *Cluster) syncExtensions(databaseName string, extensions map[string]string) error { c.setProcessName("syncing database extensions") createExtensions := make(map[string]string) @@ -837,6 +836,14 @@ func (c *Cluster) syncExtensions(extensions map[string]string) error { if err = c.executeCreateExtension(extName, schema); err != nil { return err } + // grant privileges on objects created by the extension to default database roles + if err = c.execExtensionPostCreatePrivileges(schema, databaseName); err != nil { + return err + } + // try to grant to default schema roles, too, but defaultRoles could be false for schema + if err = c.execExtensionPostCreatePrivileges(schema, databaseName+"_"+schema); err != nil { + c.logger.Debugf("no privileges assigned to schema roles: %v", err) + } } for extName, schema := range alterExtensions { if err = c.executeAlterExtension(extName, schema); err != nil { From 03bf9f7a81ff88671a2ebab48e756cb51282d51b Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Wed, 23 Jun 2021 11:16:30 +0200 Subject: [PATCH 2/2] add SET ROLE to extension SQL commands --- pkg/cluster/database.go | 16 ++++++++-------- pkg/cluster/sync.go | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/cluster/database.go b/pkg/cluster/database.go index e7f201d0c..2ce0636b5 100644 --- a/pkg/cluster/database.go +++ b/pkg/cluster/database.go @@ -36,8 +36,8 @@ const ( createDatabaseSQL = `CREATE DATABASE "%s" OWNER "%s";` createDatabaseSchemaSQL = `SET ROLE TO "%s"; CREATE SCHEMA IF NOT EXISTS "%s" AUTHORIZATION "%s"` alterDatabaseOwnerSQL = `ALTER DATABASE "%s" OWNER TO "%s";` - createExtensionSQL = `CREATE EXTENSION IF NOT EXISTS "%s" SCHEMA "%s"` - alterExtensionSQL = `ALTER EXTENSION "%s" SET SCHEMA "%s"` + createExtensionSQL = `SET ROLE TO "%s"; CREATE EXTENSION IF NOT EXISTS "%s" SCHEMA "%s"` + alterExtensionSQL = `SET ROLE TO "%s"; ALTER EXTENSION "%s" SET SCHEMA "%s"` globalDefaultPrivilegesSQL = `SET ROLE TO "%s"; ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO "%s","%s"; @@ -504,22 +504,22 @@ func (c *Cluster) getExtensions() (dbExtensions map[string]string, err error) { // executeCreateExtension creates new extension in the given schema. // The caller is responsible for opening and closing the database connection. -func (c *Cluster) executeCreateExtension(extName, schemaName string) error { - return c.execCreateOrAlterExtension(extName, schemaName, createExtensionSQL, +func (c *Cluster) executeCreateExtension(extName, schemaName, schemaOwner string) error { + return c.execCreateOrAlterExtension(extName, schemaName, schemaOwner, createExtensionSQL, "creating extension", "create extension") } // executeAlterExtension changes the schema of the given extension. // The caller is responsible for opening and closing the database connection. -func (c *Cluster) executeAlterExtension(extName, schemaName string) error { - return c.execCreateOrAlterExtension(extName, schemaName, alterExtensionSQL, +func (c *Cluster) executeAlterExtension(extName, schemaName, schemaOwner string) error { + return c.execCreateOrAlterExtension(extName, schemaName, schemaOwner, alterExtensionSQL, "changing schema for extension", "alter extension schema") } -func (c *Cluster) execCreateOrAlterExtension(extName, schemaName, statement, doing, operation string) error { +func (c *Cluster) execCreateOrAlterExtension(extName, schemaName, schemaOwner, statement, doing, operation string) error { c.logger.Infof("%s %q schema %q", doing, extName, schemaName) - if _, err := c.pgDb.Exec(fmt.Sprintf(statement, extName, schemaName)); err != nil { + if _, err := c.pgDb.Exec(fmt.Sprintf(statement, schemaOwner, extName, schemaName)); err != nil { return fmt.Errorf("could not execute %s: %v", operation, err) } diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index 2823870e3..b017e7d26 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -833,7 +833,7 @@ func (c *Cluster) syncExtensions(databaseName string, extensions map[string]stri } for extName, schema := range createExtensions { - if err = c.executeCreateExtension(extName, schema); err != nil { + if err = c.executeCreateExtension(extName, schema, databaseName+constants.OwnerRoleNameSuffix); err != nil { return err } // grant privileges on objects created by the extension to default database roles @@ -846,7 +846,7 @@ func (c *Cluster) syncExtensions(databaseName string, extensions map[string]stri } } for extName, schema := range alterExtensions { - if err = c.executeAlterExtension(extName, schema); err != nil { + if err = c.executeAlterExtension(extName, schema, databaseName+constants.OwnerRoleNameSuffix); err != nil { return err } }